remove possible race condition

git-svn-id: file:///svn/unbound/trunk@1420 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2009-01-08 16:51:44 +00:00
parent d525f6ab69
commit bcb13a174b
2 changed files with 29 additions and 12 deletions

View file

@ -1,6 +1,7 @@
8 January 2009: Wouter 8 January 2009: Wouter
- new version of ldns-trunk (today) included as tarball, fixed - new version of ldns-trunk (today) included as tarball, fixed
bug #224, building with -j race condition. bug #224, building with -j race condition.
- remove possible race condition in the test for race conditions.
7 January 2009: Wouter 7 January 2009: Wouter
- version 1.2.0 in preparation. - version 1.2.0 in preparation.

View file

@ -45,6 +45,16 @@
#include "util/locks.h" #include "util/locks.h"
#include "util/log.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 * result list for the lookups
*/ */
@ -233,17 +243,20 @@ ext_check_result(const char* desc, int err, struct ub_result* result)
static void static void
ext_callback(void* mydata, int err, struct ub_result* result) 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; int doprint = 0;
if(my_id) { if(my_id) {
/* I have an id, make sure we are not cancelled */ /* I have an id, make sure we are not cancelled */
if(*my_id == 0) { lock_basic_lock(&my_id->lock);
printf("error: query returned, but was cancelled\n"); 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(); abort();
exit(1); exit(1);
} }
if(doprint) lock_basic_unlock(&my_id->lock);
printf("cb %d: ", *my_id);
} }
ext_check_result("ext_callback", err, result); ext_check_result("ext_callback", err, result);
log_assert(result); log_assert(result);
@ -264,29 +277,32 @@ ext_thread(void* arg)
struct ext_thr_info* inf = (struct ext_thr_info*)arg; struct ext_thr_info* inf = (struct ext_thr_info*)arg;
int i, r; int i, r;
struct ub_result* result; struct ub_result* result;
int* async_ids = NULL; struct track_id* async_ids = NULL;
log_thread_set(&inf->thread_num); log_thread_set(&inf->thread_num);
if(inf->thread_num > NUMTHR*2/3) { 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) { if(!async_ids) {
printf("out of memory\n"); printf("out of memory\n");
exit(1); exit(1);
} }
for(i=0; i<inf->numq; i++) {
lock_basic_init(&async_ids[i].lock);
}
} }
for(i=0; i<inf->numq; i++) { for(i=0; i<inf->numq; i++) {
if(async_ids) { if(async_ids) {
r = ub_resolve_async(inf->ctx, r = ub_resolve_async(inf->ctx,
inf->argv[i%inf->argc], LDNS_RR_TYPE_A, inf->argv[i%inf->argc], LDNS_RR_TYPE_A,
LDNS_RR_CLASS_IN, &async_ids[i], ext_callback, LDNS_RR_CLASS_IN, &async_ids[i], ext_callback,
&async_ids[i]); &async_ids[i].id);
checkerr("ub_resolve_async", r); checkerr("ub_resolve_async", r);
if(i > 100) { 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); checkerr("ub_cancel", r);
} }
if(i > 200) {
async_ids[i-200]=0;
}
} else if(inf->thread_num > NUMTHR/2) { } else if(inf->thread_num > NUMTHR/2) {
/* async */ /* async */
r = ub_resolve_async(inf->ctx, r = ub_resolve_async(inf->ctx,