From: ian Date: Sat, 18 Dec 2004 19:33:16 +0000 (+0000) Subject: avoid invoking callback procedures other than from event handlers, by using a zero... X-Git-Tag: debian/1.1.1~110 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=chiark-tcl.git;a=commitdiff_plain;h=b6773fb0fec2b958ae6be3e1cd0f108eab06d562 avoid invoking callback procedures other than from event handlers, by using a zero timeout handler when things are perturbed --- diff --git a/adns/adns.c b/adns/adns.c index 585ce39..d8b6e1c 100644 --- a/adns/adns.c +++ b/adns/adns.c @@ -61,8 +61,11 @@ typedef struct Query Query; typedef struct Resolver Resolver; typedef struct OptionInfo OptionInfo; -static void asynch_check(Resolver *res); -static void asynch_sethandlers(Resolver *res, int shutdown); + +static void asynch_sethandlers(Resolver *res); +static void asynch_cancelhandlers(Resolver *res); +static void asynch_perturbed(Resolver *res); + static void asynch_query_dispose(Tcl_Interp *interp, Query *query); /*---------- common resolver/query option processing ----------*/ @@ -217,7 +220,7 @@ static void destroy_resolver(Tcl_Interp *ip, Resolver *res) { } adns_finish(res->ads); } - asynch_sethandlers(res,1); + asynch_cancelhandlers(res); TFREE(res); /* fixme what about the default resolver */ } @@ -439,7 +442,7 @@ static int synch(Tcl_Interp *ip, const AdnsTclRRTypeInfo *rrtype, ec= adns_wait(res->ads,&aqu,answer_r,0); assert(!ec); - asynch_check(res); + asynch_perturbed(res); return TCL_OK; } @@ -490,11 +493,13 @@ struct Query { Tcl_Obj *xargs; }; +static void asynch_check_now(Resolver *res); + static void asynch_timerhandler(void *res_v) { Resolver *res= res_v; res->timertoken= 0; adns_processtimeouts(res->ads,0); - asynch_check(res); + asynch_check_now(res); } static void asynch_filehandler(void *res_v, int mask) { @@ -503,10 +508,12 @@ static void asynch_filehandler(void *res_v, int mask) { ec= adns_processany(res->ads); if (ec) adns_globalsystemfailure(res->ads); - asynch_check(res); + asynch_check_now(res); } -static void asynch_sethandlers(Resolver *res, int shutdown) { +static void asynch_sethandlers_generic(Resolver *res, + int shutdown /*from _cancelhandlers*/, + int immediate /*from _perturbed*/) { fd_set want[3]; int maxfd; struct timeval tv_buf, *timeout; @@ -534,7 +541,9 @@ static void asynch_sethandlers(Resolver *res, int shutdown) { Tcl_DeleteTimerHandler(res->timertoken); - if (timeout) { + if (immediate) { + res->timertoken= Tcl_CreateTimerHandler(0,asynch_timerhandler,res); + } else if (timeout) { int milliseconds; if (timeout->tv_sec >= INT_MAX/1000 - 1) @@ -548,7 +557,17 @@ static void asynch_sethandlers(Resolver *res, int shutdown) { } } -static void asynch_check(Resolver *res) { +static void asynch_sethandlers(Resolver *res) { + asynch_sethandlers_generic(res,0,0); +} +static void asynch_cancelhandlers(Resolver *res) { + asynch_sethandlers_generic(res,1,0); +} +static void asynch_perturbed(Resolver *res) { + asynch_sethandlers_generic(res,0,1); +} + +static void asynch_check_now(Resolver *res) { Tcl_Interp *interp= res->interp; adns_query aqu; adns_answer *answer; @@ -578,7 +597,7 @@ static void asynch_check(Resolver *res) { asynch_query_dispose(interp, query); } - asynch_sethandlers(res,0); + asynch_sethandlers(res); } int do_adns_asynch(ClientData cd, Tcl_Interp *ip, @@ -615,7 +634,7 @@ int do_adns_asynch(ClientData cd, Tcl_Interp *ip, x_rc: if (query) asynch_query_dispose(ip, query); - if (res) asynch_sethandlers(res,0); + if (res) asynch_perturbed(res); return rc; } @@ -623,7 +642,7 @@ int do_adns_asynch_cancel(ClientData cd, Tcl_Interp *ip, void *query_v) { Query *query= query_v; Resolver *res= query->res; asynch_query_dispose(ip, query); - asynch_sethandlers(res,0); + asynch_perturbed(res); return TCL_OK; }