diff --git a/configure b/configure index 0993722d1..fc0a44def 100755 --- a/configure +++ b/configure @@ -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 diff --git a/configure.ac b/configure.ac index 347770f0e..723bfe4fb 100644 --- a/configure.ac +++ b/configure.ac @@ -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 diff --git a/doc/Changelog b/doc/Changelog index 4943507d5..1e12c6044 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -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. diff --git a/doc/libunbound.3.in b/doc/libunbound.3.in index 96fd854b0..ad7996ec9 100644 --- a/doc/libunbound.3.in +++ b/doc/libunbound.3.in @@ -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. diff --git a/libunbound/context.h b/libunbound/context.h index e1542a6ea..8898f3ebf 100644 --- a/libunbound/context.h +++ b/libunbound/context.h @@ -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 }; /** diff --git a/libunbound/libunbound.c b/libunbound/libunbound.c index d646ffee8..9c5c79fcf 100644 --- a/libunbound/libunbound.c +++ b/libunbound/libunbound.c @@ -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"; } } diff --git a/libunbound/unbound.h b/libunbound/unbound.h index 8e52e47e8..e9e5f6ebc 100644 --- a/libunbound/unbound.h +++ b/libunbound/unbound.h @@ -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); diff --git a/testcode/asynclook.c b/testcode/asynclook.c index f0ffb808e..10e34fc1c 100644 --- a/testcode/asynclook.c +++ b/testcode/asynclook.c @@ -42,6 +42,7 @@ #include "config.h" #include "libunbound/unbound.h" +#include "libunbound/context.h" #include "util/locks.h" #include "util/log.h" @@ -301,7 +302,8 @@ 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); - checkerr("ub_cancel", r); + if(r != UB_NOID) + checkerr("ub_cancel", r); } } else if(inf->thread_num > NUMTHR/2) { /* async */ @@ -467,7 +469,8 @@ int main(int argc, char** argv) for(i=0; i