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:
Wouter Wijngaards 2009-02-05 09:48:02 +00:00
parent dfcbd8cb48
commit 78600ddee1
8 changed files with 26 additions and 7 deletions

2
configure vendored
View file

@ -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

View file

@ -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

View file

@ -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.

View file

@ -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.

View file

@ -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
};
/**

View file

@ -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";
}
}

View file

@ -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);

View file

@ -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;