From: Wouter Wijngaards Date: Tue, 22 Oct 2013 09:32:10 +0000 (+0000) Subject: - Patch from Neel Goyal: Add an API call to set an event base on an X-Git-Tag: release-1.4.22rc1~96 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5e6ac36076efbbfbe2c5f1c378a3ff4201058609;p=thirdparty%2Funbound.git - Patch from Neel Goyal: Add an API call to set an event base on an existing ub_ctx. This basically just destroys the current worker and sets the event base to the current. And fix a deadlock in ub_resolve_event – the cfglock is held when libworker_create is called. This ends up trying to acquire the lock again in context_obtain_alloc in the call chain. git-svn-id: file:///svn/unbound/trunk@2992 be551aaa-1e26-0410-a405-d3ace91eadb9 --- diff --git a/doc/Changelog b/doc/Changelog index 523f0973a..ff0f765e4 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,3 +1,11 @@ +22 Oct 2013: Wouter + - Patch from Neel Goyal: Add an API call to set an event base on an + existing ub_ctx. This basically just destroys the current worker and + sets the event base to the current. And fix a deadlock in + ub_resolve_event – the cfglock is held when libworker_create is + called. This ends up trying to acquire the lock again in + context_obtain_alloc in the call chain. + 26 Sep 2013: Wouter - unbound-event.h is installed if configured --with-libevent. It contains low-level library calls, that use libevent's event_base diff --git a/libunbound/libunbound.c b/libunbound/libunbound.c index 847ac1a54..870e37699 100644 --- a/libunbound/libunbound.c +++ b/libunbound/libunbound.c @@ -656,15 +656,14 @@ ub_resolve_event(struct ub_ctx* ctx, const char* name, int rrtype, return r; } } + lock_basic_unlock(&ctx->cfglock); if(!ctx->event_worker) { ctx->event_worker = libworker_create_event(ctx, ctx->event_base); if(!ctx->event_worker) { - lock_basic_unlock(&ctx->cfglock); return UB_INITFAIL; } } - lock_basic_unlock(&ctx->cfglock); /* create new ctx_query and attempt to add to the list */ q = context_new(ctx, name, rrtype, rrclass, (ub_callback_t)callback, @@ -1212,3 +1211,24 @@ const char* ub_version(void) { return PACKAGE_VERSION; } + +int +ub_ctx_set_event(struct ub_ctx* ctx, struct event_base* base) { + if (!ctx || !ctx->event_base || !base) { + return UB_INITFAIL; + } + if (ctx->event_base == base) { + /* already set */ + return UB_NOERROR; + } + + lock_basic_lock(&ctx->cfglock); + /* destroy the current worker - safe to pass in NULL */ + libworker_delete_event(ctx->event_worker); + ctx->event_worker = NULL; + ctx->event_base = base; + ctx->created_bg = 0; + ctx->dothread = 1; + lock_basic_unlock(&ctx->cfglock); + return UB_NOERROR; +} diff --git a/libunbound/ubsyms.def b/libunbound/ubsyms.def index 26040921b..866c1764c 100644 --- a/libunbound/ubsyms.def +++ b/libunbound/ubsyms.def @@ -29,3 +29,4 @@ ub_ctx_zone_remove ub_ctx_data_add ub_ctx_data_remove ub_version +ub_ctx_set_event diff --git a/libunbound/unbound-event.h b/libunbound/unbound-event.h index 519e4e0de..c49005eec 100644 --- a/libunbound/unbound-event.h +++ b/libunbound/unbound-event.h @@ -63,9 +63,9 @@ extern "C" { struct ub_ctx; struct ub_result; struct event_base; -struct ldns_buffer; +struct ldns_struct_buffer; -typedef void (*ub_event_callback_t)(void*, int, struct ldns_buffer*, int, char*); +typedef void (*ub_event_callback_t)(void*, int, struct ldns_struct_buffer*, int, char*); /** * Create a resolving and validation context. @@ -81,6 +81,15 @@ typedef void (*ub_event_callback_t)(void*, int, struct ldns_buffer*, int, char*) */ struct ub_ctx* ub_ctx_create_event(struct event_base* base); +/** + * Set a new event_base on a context created with ub_ctx_create_event. + * Any outbound queries will be canceled. + * @param ctx the ub_ctx to update. Must have been created with ub_ctx_create_event + * @param base the new event_base to attach to the ctx + * @return 0 if OK, else error + */ +int ub_ctx_set_event(struct ub_ctx* ctx, struct event_base* base); + /** * Perform resolution and validation of the target name. * Asynchronous, after a while, the callback will be called with your