mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-24 00:29:58 -05:00
Fixup race condition in ub_cancel. For 1.3.0.
git-svn-id: file:///svn/unbound/trunk@1451 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
dfcbd8cb48
commit
78600ddee1
8 changed files with 26 additions and 7 deletions
2
configure
vendored
2
configure
vendored
|
|
@ -1945,7 +1945,7 @@ LIBUNBOUND_AGE=0
|
||||||
# 1.1.1 had 0:16:0
|
# 1.1.1 had 0:16:0
|
||||||
# 1.2.0 had 0:17:0
|
# 1.2.0 had 0:17:0
|
||||||
# 1.2.1 had 0:18:0
|
# 1.2.1 had 0:18:0
|
||||||
# 1.3.0 had 0:19:0
|
# 1.3.0 had 1:0:1
|
||||||
|
|
||||||
# Current -- the number of the binary API that we're implementing
|
# Current -- the number of the binary API that we're implementing
|
||||||
# Revision -- which iteration of the implementation of the binary
|
# Revision -- which iteration of the implementation of the binary
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ LIBUNBOUND_AGE=0
|
||||||
# 1.1.1 had 0:16:0
|
# 1.1.1 had 0:16:0
|
||||||
# 1.2.0 had 0:17:0
|
# 1.2.0 had 0:17:0
|
||||||
# 1.2.1 had 0:18:0
|
# 1.2.1 had 0:18:0
|
||||||
# 1.3.0 had 0:19:0
|
# 1.3.0 had 1:0:1
|
||||||
|
|
||||||
# Current -- the number of the binary API that we're implementing
|
# Current -- the number of the binary API that we're implementing
|
||||||
# Revision -- which iteration of the implementation of the binary
|
# Revision -- which iteration of the implementation of the binary
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,12 @@
|
||||||
5 February 2009: Wouter
|
5 February 2009: Wouter
|
||||||
- ldns 1.5.0 rc as tarball included.
|
- ldns 1.5.0 rc as tarball included.
|
||||||
|
- 1.3.0 development continues:
|
||||||
|
change in libunbound API: ub_cancel can return an error, that
|
||||||
|
the async_id did not exist, or that it was already delivered.
|
||||||
|
The result could have been delivered just before the cancel
|
||||||
|
routine managed to acquire the lock, so a caller may get the
|
||||||
|
result at the same time they call cancel. For this case,
|
||||||
|
ub_cancel tries to return an error code.
|
||||||
|
|
||||||
4 February 2009: Wouter
|
4 February 2009: Wouter
|
||||||
- tag for release 1.2.1.
|
- tag for release 1.2.1.
|
||||||
|
|
|
||||||
|
|
@ -281,7 +281,8 @@ The async_id is returned so you can (at your option) decide to track it
|
||||||
and cancel the request if needed.
|
and cancel the request if needed.
|
||||||
.TP
|
.TP
|
||||||
.B ub_cancel
|
.B ub_cancel
|
||||||
Cancel an async query in progress.
|
Cancel an async query in progress. This may return an error if the query
|
||||||
|
does not exist, or was already delivered.
|
||||||
.TP
|
.TP
|
||||||
.B ub_resolve_free
|
.B ub_resolve_free
|
||||||
Free struct ub_result contents after use.
|
Free struct ub_result contents after use.
|
||||||
|
|
|
||||||
|
|
@ -184,7 +184,9 @@ enum ub_ctx_err {
|
||||||
/** error in pipe communication with async bg worker */
|
/** error in pipe communication with async bg worker */
|
||||||
UB_PIPE = -8,
|
UB_PIPE = -8,
|
||||||
/** error reading from file (resolv.conf) */
|
/** error reading from file (resolv.conf) */
|
||||||
UB_READFILE = -9
|
UB_READFILE = -9,
|
||||||
|
/** error async_id does not exist or result already been delivered */
|
||||||
|
UB_NOID = -10
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -642,7 +642,7 @@ ub_cancel(struct ub_ctx* ctx, int async_id)
|
||||||
if(!q || !q->async) {
|
if(!q || !q->async) {
|
||||||
/* it is not there, so nothing to do */
|
/* it is not there, so nothing to do */
|
||||||
lock_basic_unlock(&ctx->cfglock);
|
lock_basic_unlock(&ctx->cfglock);
|
||||||
return UB_NOERROR;
|
return UB_NOID;
|
||||||
}
|
}
|
||||||
log_assert(q->async);
|
log_assert(q->async);
|
||||||
q->cancelled = 1;
|
q->cancelled = 1;
|
||||||
|
|
@ -703,6 +703,7 @@ ub_strerror(int err)
|
||||||
case UB_AFTERFINAL: return "setting change after finalize";
|
case UB_AFTERFINAL: return "setting change after finalize";
|
||||||
case UB_PIPE: return "error in pipe communication with async";
|
case UB_PIPE: return "error in pipe communication with async";
|
||||||
case UB_READFILE: return "error reading file";
|
case UB_READFILE: return "error reading file";
|
||||||
|
case UB_NOID: return "error async_id does not exist";
|
||||||
default: return "unknown error";
|
default: return "unknown error";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -449,6 +449,11 @@ int ub_resolve_async(struct ub_ctx* ctx, char* name, int rrtype,
|
||||||
* @param ctx: context.
|
* @param ctx: context.
|
||||||
* @param async_id: which query to cancel.
|
* @param async_id: which query to cancel.
|
||||||
* @return 0 if OK, else error.
|
* @return 0 if OK, else error.
|
||||||
|
* This routine can return an error if the async_id passed does not exist
|
||||||
|
* or has already been delivered. If another thread is processing results
|
||||||
|
* at the same time, the result may be delivered at the same time and the
|
||||||
|
* cancel fails with an error. Also the cancel can fail due to a system
|
||||||
|
* error, no memory or socket failures.
|
||||||
*/
|
*/
|
||||||
int ub_cancel(struct ub_ctx* ctx, int async_id);
|
int ub_cancel(struct ub_ctx* ctx, int async_id);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "libunbound/unbound.h"
|
#include "libunbound/unbound.h"
|
||||||
|
#include "libunbound/context.h"
|
||||||
#include "util/locks.h"
|
#include "util/locks.h"
|
||||||
#include "util/log.h"
|
#include "util/log.h"
|
||||||
|
|
||||||
|
|
@ -301,7 +302,8 @@ ext_thread(void* arg)
|
||||||
r = ub_cancel(inf->ctx, async_ids[i-100].id);
|
r = ub_cancel(inf->ctx, async_ids[i-100].id);
|
||||||
async_ids[i-100].cancel=1;
|
async_ids[i-100].cancel=1;
|
||||||
lock_basic_unlock(&async_ids[i-100].lock);
|
lock_basic_unlock(&async_ids[i-100].lock);
|
||||||
checkerr("ub_cancel", r);
|
if(r != UB_NOID)
|
||||||
|
checkerr("ub_cancel", r);
|
||||||
}
|
}
|
||||||
} else if(inf->thread_num > NUMTHR/2) {
|
} else if(inf->thread_num > NUMTHR/2) {
|
||||||
/* async */
|
/* async */
|
||||||
|
|
@ -467,7 +469,8 @@ int main(int argc, char** argv)
|
||||||
for(i=0; i<argc; i++) {
|
for(i=0; i<argc; i++) {
|
||||||
fprintf(stderr, "cancel %s\n", argv[i]);
|
fprintf(stderr, "cancel %s\n", argv[i]);
|
||||||
r = ub_cancel(ctx, lookups[i].async_id);
|
r = ub_cancel(ctx, lookups[i].async_id);
|
||||||
checkerr("ub_cancel", r);
|
if(r != UB_NOID)
|
||||||
|
checkerr("ub_cancel", r);
|
||||||
}
|
}
|
||||||
num_wait = 0;
|
num_wait = 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue