]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
more fixes, more tests.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Fri, 25 Jan 2008 15:45:54 +0000 (15:45 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Fri, 25 Jan 2008 15:45:54 +0000 (15:45 +0000)
git-svn-id: file:///svn/unbound/trunk@903 be551aaa-1e26-0410-a405-d3ace91eadb9

doc/Changelog
libunbound/context.c
libunbound/context.h
libunbound/worker.c
libunbound/worker.h
testdata/05-asynclook.tpkg

index dfa6297cfad0354ab7b0179a3a3eb8d9ed3c635c..f4fcc428e1830dcdad8d301f7ad731eddcf1da9c 100644 (file)
        - fix pass async_id=NULL to _async resolve().
        - rewrote _wait() routine, so that it is threadsafe.
        - cancelation is threadsafe.
+       - asynclook extended test in tpkg.
+       - fixed two races where forked bg process waits for (somehow shared?)
+         locks, so does not service the query pipe on the bg side.
+         Now those locks are only held for fg_threads and for bg_as_a_thread.
 
 24 January 2008: Wouter
        - tested the cancel() function.
index c1436121fc143e2c8b16ceaa9880e079832fe8c6..26a03c8edd557f446eff3c1e39bca565c8f143ec 100644 (file)
@@ -162,16 +162,20 @@ context_new(struct ub_val_ctx* ctx, char* name, int rrtype, int rrclass,
 }
 
 struct alloc_cache* 
-context_obtain_alloc(struct ub_val_ctx* ctx)
+context_obtain_alloc(struct ub_val_ctx* ctx, int locking)
 {
        struct alloc_cache* a;
        int tnum = 0;
-       lock_basic_lock(&ctx->cfglock);
+       if(locking) {
+               lock_basic_lock(&ctx->cfglock);
+       }
        a = ctx->alloc_list;
        if(a)
                ctx->alloc_list = a->super; /* snip off list */
        else    tnum = ctx->thr_next_num++;
-       lock_basic_unlock(&ctx->cfglock);
+       if(locking) {
+               lock_basic_unlock(&ctx->cfglock);
+       }
        if(a) {
                a->super = &ctx->superalloc;
                return a;
@@ -184,14 +188,19 @@ context_obtain_alloc(struct ub_val_ctx* ctx)
 }
 
 void 
-context_release_alloc(struct ub_val_ctx* ctx, struct alloc_cache* alloc)
+context_release_alloc(struct ub_val_ctx* ctx, struct alloc_cache* alloc,
+       int locking)
 {
        if(!ctx || !alloc)
                return;
-       lock_basic_lock(&ctx->cfglock);
+       if(locking) {
+               lock_basic_lock(&ctx->cfglock);
+       }
        alloc->super = ctx->alloc_list;
        ctx->alloc_list = alloc;
-       lock_basic_unlock(&ctx->cfglock);
+       if(locking) {
+               lock_basic_unlock(&ctx->cfglock);
+       }
 }
 
 uint8_t* 
index 5be7dc8acb6ca10caf192037bab221e05b923294..80b10d9671bc43fb51d6d6feca6c87bd92e67fa1 100644 (file)
@@ -231,16 +231,19 @@ struct ctx_query* context_new(struct ub_val_ctx* ctx, char* name, int rrtype,
 /**
  * Get a new alloc. Creates a new one or uses a cached one.
  * @param ctx: context
+ * @param locking: if true, cfglock is locked while getting alloc.
  * @return an alloc, or NULL on mem error.
  */
-struct alloc_cache* context_obtain_alloc(struct ub_val_ctx* ctx);
+struct alloc_cache* context_obtain_alloc(struct ub_val_ctx* ctx, int locking);
 
 /**
  * Release an alloc. Puts it into the cache.
  * @param ctx: context
+ * @param locking: if true, cfglock is locked while releasing alloc.
  * @param alloc: alloc to relinquish.
  */
-void context_release_alloc(struct ub_val_ctx* ctx, struct alloc_cache* alloc);
+void context_release_alloc(struct ub_val_ctx* ctx, struct alloc_cache* alloc,
+       int locking);
 
 /**
  * Serialize a context query that questions data.
index c387b7f748a83f6465930dbcc12308b656ae6169..feb1985b758b09d87c3ce54de2302ca871df5b19 100644 (file)
@@ -74,7 +74,8 @@ libworker_delete(struct libworker* w)
        if(!w) return;
        if(w->env) {
                mesh_delete(w->env->mesh);
-               context_release_alloc(w->ctx, w->env->alloc);
+               context_release_alloc(w->ctx, w->env->alloc, 
+                       !w->is_bg || w->is_bg_thread);
                ldns_buffer_free(w->env->scratch_buffer);
                regional_destroy(w->env->scratch);
                ub_randfree(w->env->rnd);
@@ -90,12 +91,13 @@ libworker_delete(struct libworker* w)
 
 /** setup fresh libworker struct */
 static struct libworker*
-libworker_setup(struct ub_val_ctx* ctx)
+libworker_setup(struct ub_val_ctx* ctx, int is_bg)
 {
        unsigned int seed;
        struct libworker* w = (struct libworker*)calloc(1, sizeof(*w));
        struct config_file* cfg = ctx->env->cfg;
        if(!w) return NULL;
+       w->is_bg = is_bg;
        w->ctx = ctx;
        w->env = (struct module_env*)malloc(sizeof(*w->env));
        if(!w->env) {
@@ -103,7 +105,7 @@ libworker_setup(struct ub_val_ctx* ctx)
                return NULL;
        }
        *w->env = *ctx->env;
-       w->env->alloc = context_obtain_alloc(ctx);
+       w->env->alloc = context_obtain_alloc(ctx, !w->is_bg || w->is_bg_thread);
        if(!w->env->alloc) {
                libworker_delete(w);
                return NULL;
@@ -125,16 +127,20 @@ libworker_setup(struct ub_val_ctx* ctx)
        seed = (unsigned int)time(NULL) ^ (unsigned int)getpid() ^
                (((unsigned int)w->thread_num)<<17);
        seed ^= (unsigned int)w->env->alloc->next_id;
-       lock_basic_lock(&ctx->cfglock);
-       /* Openssl RAND_... functions are not as threadsafe as documented,
-        * put a lock around them. */
+       if(!w->is_bg || w->is_bg_thread) {
+               /* Openssl RAND_... functions are not as threadsafe 
+                * as documented, put a lock around them. */
+               lock_basic_lock(&ctx->cfglock);
+       }
        if(!ub_initstate(seed, w->env->rnd, RND_STATE_SIZE)) {
                lock_basic_unlock(&ctx->cfglock);
                seed = 0;
                libworker_delete(w);
                return NULL;
        }
-       lock_basic_unlock(&ctx->cfglock);
+       if(!w->is_bg || w->is_bg_thread) {
+               lock_basic_unlock(&ctx->cfglock);
+       }
        seed = 0;
 
        w->base = comm_base_create();
@@ -311,7 +317,7 @@ int libworker_bg(struct ub_val_ctx* ctx)
        lock_basic_lock(&ctx->cfglock);
        if(ctx->dothread) {
                lock_basic_unlock(&ctx->cfglock);
-               w = libworker_setup(ctx);
+               w = libworker_setup(ctx, 1);
                w->is_bg_thread = 1;
 #ifdef ENABLE_LOCK_CHECKS
                w->thread_num = 1; /* for nicer DEBUG checklocks */
@@ -322,7 +328,7 @@ int libworker_bg(struct ub_val_ctx* ctx)
                lock_basic_unlock(&ctx->cfglock);
                switch((ctx->bg_pid=fork())) {
                        case 0:
-                               w = libworker_setup(ctx);
+                               w = libworker_setup(ctx, 1);
                                if(!w) fatal_exit("out of memory");
                                /* close non-used parts of the pipes */
                                close(ctx->qqpipe[1]);
@@ -490,7 +496,7 @@ setup_qinfo_edns(struct libworker* w, struct ctx_query* q,
 
 int libworker_fg(struct ub_val_ctx* ctx, struct ctx_query* q)
 {
-       struct libworker* w = libworker_setup(ctx);
+       struct libworker* w = libworker_setup(ctx, 0);
        uint16_t qflags, qid;
        struct query_info qinfo;
        struct edns_data edns;
index f1969b99dd19c554b684eb07b7e31c05d430df42..275f10463e4c174b54c407837ee0be701fbe8d37 100644 (file)
@@ -68,6 +68,8 @@ struct libworker {
        /** context we are operating under */
        struct ub_val_ctx* ctx;
 
+       /** is this the bg worker? */
+       int is_bg;
        /** is this a bg worker that is threaded (not forked)? */
        int is_bg_thread;
 
index 4e4b5b6d888627e3430202390a45f0c6331c0678..e1d7d555c47a838a2e218aa72abb73b072ea0b77 100644 (file)
Binary files a/testdata/05-asynclook.tpkg and b/testdata/05-asynclook.tpkg differ