# 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.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
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.
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.
/** 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
};
/**
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;
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";
}
}
* @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);
#include "config.h"
#include "libunbound/unbound.h"
+#include "libunbound/context.h"
#include "util/locks.h"
#include "util/log.h"
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 */
for(i=0; i<argc; i++) {
fprintf(stderr, "cancel %s\n", argv[i]);
r = ub_cancel(ctx, lookups[i].async_id);
- checkerr("ub_cancel", r);
+ if(r != UB_NOID)
+ checkerr("ub_cancel", r);
}
num_wait = 0;
}