From bcb13a174be124429b9d78813c84a87c0160312a Mon Sep 17 00:00:00 2001 From: Wouter Wijngaards Date: Thu, 8 Jan 2009 16:51:44 +0000 Subject: [PATCH] remove possible race condition git-svn-id: file:///svn/unbound/trunk@1420 be551aaa-1e26-0410-a405-d3ace91eadb9 --- doc/Changelog | 1 + testcode/asynclook.c | 40 ++++++++++++++++++++++++++++------------ 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/doc/Changelog b/doc/Changelog index 7bc3af5bc..b69dfda14 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,6 +1,7 @@ 8 January 2009: Wouter - new version of ldns-trunk (today) included as tarball, fixed bug #224, building with -j race condition. + - remove possible race condition in the test for race conditions. 7 January 2009: Wouter - version 1.2.0 in preparation. diff --git a/testcode/asynclook.c b/testcode/asynclook.c index b2c8f5530..f0ffb808e 100644 --- a/testcode/asynclook.c +++ b/testcode/asynclook.c @@ -45,6 +45,16 @@ #include "util/locks.h" #include "util/log.h" +/** keeping track of the async ids */ +struct track_id { + /** the id to pass to libunbound to cancel */ + int id; + /** true if cancelled */ + int cancel; + /** a lock on this structure for thread safety */ + lock_basic_t lock; +}; + /** * result list for the lookups */ @@ -233,17 +243,20 @@ ext_check_result(const char* desc, int err, struct ub_result* result) static void ext_callback(void* mydata, int err, struct ub_result* result) { - int* my_id = (int*)mydata; + struct track_id* my_id = (struct track_id*)mydata; int doprint = 0; if(my_id) { /* I have an id, make sure we are not cancelled */ - if(*my_id == 0) { - printf("error: query returned, but was cancelled\n"); + lock_basic_lock(&my_id->lock); + if(doprint) + printf("cb %d: ", my_id->id); + if(my_id->cancel) { + printf("error: query id=%d returned, but was cancelled\n", + my_id->id); abort(); exit(1); } - if(doprint) - printf("cb %d: ", *my_id); + lock_basic_unlock(&my_id->lock); } ext_check_result("ext_callback", err, result); log_assert(result); @@ -264,29 +277,32 @@ ext_thread(void* arg) struct ext_thr_info* inf = (struct ext_thr_info*)arg; int i, r; struct ub_result* result; - int* async_ids = NULL; + struct track_id* async_ids = NULL; log_thread_set(&inf->thread_num); if(inf->thread_num > NUMTHR*2/3) { - async_ids = (int*)calloc((size_t)inf->numq, sizeof(int)); + async_ids = (struct track_id*)calloc((size_t)inf->numq, sizeof(struct track_id)); if(!async_ids) { printf("out of memory\n"); exit(1); } + for(i=0; inumq; i++) { + lock_basic_init(&async_ids[i].lock); + } } for(i=0; inumq; i++) { if(async_ids) { r = ub_resolve_async(inf->ctx, inf->argv[i%inf->argc], LDNS_RR_TYPE_A, LDNS_RR_CLASS_IN, &async_ids[i], ext_callback, - &async_ids[i]); + &async_ids[i].id); checkerr("ub_resolve_async", r); if(i > 100) { - r = ub_cancel(inf->ctx, async_ids[i-100]); + lock_basic_lock(&async_ids[i-100].lock); + 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(i > 200) { - async_ids[i-200]=0; - } } else if(inf->thread_num > NUMTHR/2) { /* async */ r = ub_resolve_async(inf->ctx,