mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-01-02 12:59:36 -05:00
more fixes, more tests.
git-svn-id: file:///svn/unbound/trunk@903 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
ed57c4de4c
commit
32396dc677
6 changed files with 42 additions and 18 deletions
|
|
@ -11,6 +11,10 @@
|
|||
- 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.
|
||||
|
|
|
|||
|
|
@ -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*
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
BIN
testdata/05-asynclook.tpkg
vendored
BIN
testdata/05-asynclook.tpkg
vendored
Binary file not shown.
Loading…
Reference in a new issue