From 79afa3a523e92a1d552d46729b1e1d04db97f72c Mon Sep 17 00:00:00 2001 From: ian Date: Mon, 27 Dec 2004 16:26:16 +0000 Subject: [PATCH] get resolver destruction right --- adns/adns.c | 64 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 27 deletions(-) diff --git a/adns/adns.c b/adns/adns.c index 78b6d79..d57c49b 100644 --- a/adns/adns.c +++ b/adns/adns.c @@ -287,10 +287,11 @@ static void destroy_resolver(Tcl_Interp *ip, Resolver *res) { asynch_query_dispose(ip, query_v); } adns_finish(res->ads); + res->ads= 0; } asynch_cancelhandlers(res); scriptinv_cancel(&res->errcallback); - TFREE(res); + Tcl_EventuallyFree(res, Tcl_Free); } static void destroy_resolver_idtabcb(Tcl_Interp *ip, void *resolver_v) { @@ -430,33 +431,36 @@ static const OptionInfo query_optioninfos[]= { static int query_submit(Tcl_Interp *ip, const AdnsTclRRTypeInfo *type, const char *domain, int queryopts_objc, Tcl_Obj *const *queryopts_objv, - adns_query *aqu_r, void *context, OptionParse *op) { + adns_query *aqu_r, void *context, Resolver **res_r) { struct sockaddr sa; static const int aftry[]= { AF_INET, AF_INET6 }; + OptionParse op; OptionParse res_op; int rc, r, ec; adns_state ads; - op->aflags= adns_qf_owner; - op->sflags= 0; - op->resolver= 0; - op->reverseany= 0; - rc= parse_options(ip, queryopts_objc,queryopts_objv, query_optioninfos,op); + op.aflags= adns_qf_owner; + op.sflags= 0; + op.resolver= 0; + op.reverseany= 0; + rc= parse_options(ip, queryopts_objc,queryopts_objv, query_optioninfos,&op); if (rc) return rc; - if (!op->resolver) { - op->resolver= default_resolver(ip); - if (!op->resolver) { + if (!op.resolver) { + op.resolver= default_resolver(ip); + if (!op.resolver) { optparse_blank(&res_op); - rc= create_resolver(ip, &res_op, &op->resolver); + rc= create_resolver(ip, &res_op, &op.resolver); if (rc) return rc; Tcl_SetAssocData(ip, ASSOC_DEFAULTRES, - destroy_resolver_defcb, op->resolver); + destroy_resolver_defcb, op.resolver); } } + + *res_r= op.resolver; - if (op->reverseany || (op->sflags & oisf_reverse)) { + if (op.reverseany || (op.sflags & oisf_reverse)) { const int *af; for (af=aftry; af < af + sizeof(af)/sizeof(*af); af++) { memset(&sa,0,sizeof(sa)); @@ -468,17 +472,17 @@ static int query_submit(Tcl_Interp *ip, af_found:; } - ads= op->resolver->ads; + ads= op.resolver->ads; - if (op->reverseany) { - ec= adns_submit_reverse_any(ads, &sa, op->reverseany, - type->number, op->aflags, context, aqu_r); - } else if (op->sflags & oisf_reverse) { + if (op.reverseany) { + ec= adns_submit_reverse_any(ads, &sa, op.reverseany, + type->number, op.aflags, context, aqu_r); + } else if (op.sflags & oisf_reverse) { ec= adns_submit_reverse(ads, &sa, - type->number, op->aflags, context, aqu_r); + type->number, op.aflags, context, aqu_r); } else { ec= adns_submit(ads, domain, - type->number, op->aflags, context, aqu_r); + type->number, op.aflags, context, aqu_r); } if (ec) return posixerr(ip,ec,"submit adns query"); @@ -533,14 +537,12 @@ static int synch(Tcl_Interp *ip, const AdnsTclRRTypeInfo *rrtype, const char *domain, int objc, Tcl_Obj *const *objv, adns_answer **answer_r) { adns_query aqu; - OptionParse op; Resolver *res; int rc, ec; - rc= query_submit(ip,rrtype,domain,objc,objv,&aqu,0,&op); + rc= query_submit(ip,rrtype,domain,objc,objv,&aqu,0,&res); if (rc) return rc; - res= op.resolver; ec= adns_wait(res->ads,&aqu,answer_r,0); assert(!ec); @@ -685,7 +687,14 @@ static void asynch_check_now(Resolver *res) { int ec; Tcl_Obj *results[RESULTLIST_LLEN]; + Tcl_Preserve(res); + for (;;) { + if (!res->ads) { /* oh, it has been destroyed! */ + Tcl_Release(res); + return; + } + aqu= 0; ec= adns_check(res->ads, &aqu, &answer, &query_v); if (ec==ESRCH || ec==EAGAIN) break; @@ -706,6 +715,8 @@ static void asynch_check_now(Resolver *res) { } asynch_sethandlers(res); + + Tcl_Release(res); } int do_adns_asynch(ClientData cd, Tcl_Interp *ip, @@ -715,8 +726,7 @@ int do_adns_asynch(ClientData cd, Tcl_Interp *ip, int objc, Tcl_Obj *const *objv, void **result) { Query *query; int rc; - Resolver *res=0; - OptionParse op; + Resolver *res= 0; query= TALLOC(sizeof(*query)); query->ix= -1; @@ -726,10 +736,10 @@ int do_adns_asynch(ClientData cd, Tcl_Interp *ip, scriptinv_init(&query->on_fail); query->xargs= 0; - rc= query_submit(ip,rrtype,domain,objc,objv,&query->aqu,query,&op); + rc= query_submit(ip,rrtype,domain,objc,objv,&query->aqu,query,&query->res); if (rc) goto x_rc; - res= op.resolver; + res= query->res; rc= scriptinv_set(&query->on_yes, ip,on_yes, xargs); if (rc) goto x_rc; rc= scriptinv_set(&query->on_no, ip,on_no, xargs); if (rc) goto x_rc; -- 2.30.2