mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -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.2.0 had 0:17: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
|
||||
# Revision -- which iteration of the implementation of the binary
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ LIBUNBOUND_AGE=0
|
|||
# 1.1.1 had 0:16:0
|
||||
# 1.2.0 had 0:17: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
|
||||
# Revision -- which iteration of the implementation of the binary
|
||||
|
|
|
|||
|
|
@ -1,5 +1,12 @@
|
|||
5 February 2009: Wouter
|
||||
- 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
|
||||
- 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.
|
||||
.TP
|
||||
.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
|
||||
.B ub_resolve_free
|
||||
Free struct ub_result contents after use.
|
||||
|
|
|
|||
|
|
@ -184,7 +184,9 @@ enum ub_ctx_err {
|
|||
/** error in pipe communication with async bg worker */
|
||||
UB_PIPE = -8,
|
||||
/** 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) {
|
||||
/* it is not there, so nothing to do */
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
return UB_NOERROR;
|
||||
return UB_NOID;
|
||||
}
|
||||
log_assert(q->async);
|
||||
q->cancelled = 1;
|
||||
|
|
@ -703,6 +703,7 @@ ub_strerror(int err)
|
|||
case UB_AFTERFINAL: return "setting change after finalize";
|
||||
case UB_PIPE: return "error in pipe communication with async";
|
||||
case UB_READFILE: return "error reading file";
|
||||
case UB_NOID: return "error async_id does not exist";
|
||||
default: return "unknown error";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -449,6 +449,11 @@ int ub_resolve_async(struct ub_ctx* ctx, char* name, int rrtype,
|
|||
* @param ctx: context.
|
||||
* @param async_id: which query to cancel.
|
||||
* @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);
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@
|
|||
|
||||
#include "config.h"
|
||||
#include "libunbound/unbound.h"
|
||||
#include "libunbound/context.h"
|
||||
#include "util/locks.h"
|
||||
#include "util/log.h"
|
||||
|
||||
|
|
@ -301,6 +302,7 @@ ext_thread(void* arg)
|
|||
r = ub_cancel(inf->ctx, async_ids[i-100].id);
|
||||
async_ids[i-100].cancel=1;
|
||||
lock_basic_unlock(&async_ids[i-100].lock);
|
||||
if(r != UB_NOID)
|
||||
checkerr("ub_cancel", r);
|
||||
}
|
||||
} else if(inf->thread_num > NUMTHR/2) {
|
||||
|
|
@ -467,6 +469,7 @@ int main(int argc, char** argv)
|
|||
for(i=0; i<argc; i++) {
|
||||
fprintf(stderr, "cancel %s\n", argv[i]);
|
||||
r = ub_cancel(ctx, lookups[i].async_id);
|
||||
if(r != UB_NOID)
|
||||
checkerr("ub_cancel", r);
|
||||
}
|
||||
num_wait = 0;
|
||||
|
|
|
|||
Loading…
Reference in a new issue