- 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
This commit is contained in:
Wouter Wijngaards 2013-10-22 09:32:10 +00:00
parent 5af60910c9
commit 5e6ac36076
4 changed files with 42 additions and 4 deletions

View file

@ -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 26 Sep 2013: Wouter
- unbound-event.h is installed if configured --with-libevent. It - unbound-event.h is installed if configured --with-libevent. It
contains low-level library calls, that use libevent's event_base contains low-level library calls, that use libevent's event_base

View file

@ -656,15 +656,14 @@ ub_resolve_event(struct ub_ctx* ctx, const char* name, int rrtype,
return r; return r;
} }
} }
lock_basic_unlock(&ctx->cfglock);
if(!ctx->event_worker) { if(!ctx->event_worker) {
ctx->event_worker = libworker_create_event(ctx, ctx->event_worker = libworker_create_event(ctx,
ctx->event_base); ctx->event_base);
if(!ctx->event_worker) { if(!ctx->event_worker) {
lock_basic_unlock(&ctx->cfglock);
return UB_INITFAIL; return UB_INITFAIL;
} }
} }
lock_basic_unlock(&ctx->cfglock);
/* create new ctx_query and attempt to add to the list */ /* create new ctx_query and attempt to add to the list */
q = context_new(ctx, name, rrtype, rrclass, (ub_callback_t)callback, q = context_new(ctx, name, rrtype, rrclass, (ub_callback_t)callback,
@ -1212,3 +1211,24 @@ const char* ub_version(void)
{ {
return PACKAGE_VERSION; 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;
}

View file

@ -29,3 +29,4 @@ ub_ctx_zone_remove
ub_ctx_data_add ub_ctx_data_add
ub_ctx_data_remove ub_ctx_data_remove
ub_version ub_version
ub_ctx_set_event

View file

@ -63,9 +63,9 @@ extern "C" {
struct ub_ctx; struct ub_ctx;
struct ub_result; struct ub_result;
struct event_base; 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. * 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); 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. * Perform resolution and validation of the target name.
* Asynchronous, after a while, the callback will be called with your * Asynchronous, after a while, the callback will be called with your