--- cvsroot/EV-ADNS/ADNS.xs 2007/12/01 21:01:32 1.7 +++ cvsroot/EV-ADNS/ADNS.xs 2007/12/07 23:54:13 1.12 @@ -7,9 +7,6 @@ #include "EVAPI.h" -static HV *stash; -static adns_state ads; - struct ctx { SV *self; @@ -28,7 +25,7 @@ } static void -process () +process (adns_state ads) { dSP; @@ -71,7 +68,18 @@ break; case adns_r_txt: - sv = newSVpvn (a->rrs.manyistr [i]->str, a->rrs.manyistr [i]->i); + { + AV *av = newAV (); + adns_rr_intstr *rr = a->rrs.manyistr [i]; + + while (rr->str) + { + av_push (av, newSVpvn (rr->str, rr->i)); + ++rr; + } + + sv = newRV_noinc ((SV *)av); + } break; case adns_r_a: @@ -86,11 +94,12 @@ { /* untested */ AV *av = newAV (); - sv = newRV_noinc ((SV *)av); adns_rr_intstrpair *rr = a->rrs.intstrpair + i; av_push (av, newSVpvn (rr->array [0].str, rr->array [0].i)); av_push (av, newSVpvn (rr->array [1].str, rr->array [1].i)); + + sv = newRV_noinc ((SV *)av); } break; @@ -99,33 +108,36 @@ { /* untested */ AV *av = newAV (); - sv = newRV_noinc ((SV *)av); adns_rr_strpair *rr = a->rrs.strpair + i; av_push (av, newSVpv (rr->array [0], 0)); av_push (av, newSVpv (rr->array [1], 0)); + + sv = newRV_noinc ((SV *)av); } break; case adns_r_mx: { AV *av = newAV (); - sv = newRV_noinc ((SV *)av); adns_rr_inthostaddr *rr = a->rrs.inthostaddr + i; av_push (av, newSViv (rr->i)); av_push (av, ha2sv (&rr->ha)); + + sv = newRV_noinc ((SV *)av); } break; case adns_r_mx_raw: { AV *av = newAV (); - sv = newRV_noinc ((SV *)av); adns_rr_intstr *rr = a->rrs.intstr + i; av_push (av, newSViv (rr->i)); av_push (av, newSVpv (rr->str, 0)); + + sv = newRV_noinc ((SV *)av); } break; @@ -133,7 +145,6 @@ case adns_r_soa_raw: { AV *av = newAV (); - sv = newRV_noinc ((SV *)av); adns_rr_soa *rr = a->rrs.soa + i; av_push (av, newSVpv (rr->mname, 0)); @@ -143,32 +154,36 @@ av_push (av, newSVuv (rr->retry)); av_push (av, newSVuv (rr->expire)); av_push (av, newSVuv (rr->minimum)); + + sv = newRV_noinc ((SV *)av); } break; case adns_r_srv_raw: { AV *av = newAV (); - sv = newRV_noinc ((SV *)av); adns_rr_srvraw *rr = a->rrs.srvraw + i; av_push (av, newSViv (rr->priority)); av_push (av, newSViv (rr->weight)); av_push (av, newSViv (rr->port)); av_push (av, newSVpv (rr->host, 0)); + + sv = newRV_noinc ((SV *)av); } break; case adns_r_srv: { AV *av = newAV (); - sv = newRV_noinc ((SV *)av); adns_rr_srvha *rr = a->rrs.srvha + i; av_push (av, newSViv (rr->priority)); av_push (av, newSViv (rr->weight)); av_push (av, newSViv (rr->port)); av_push (av, ha2sv (&rr->ha)); + + sv = newRV_noinc ((SV *)av); } break; @@ -199,7 +214,8 @@ static int nfd, mfd; static ev_io *iow; static ev_timer tw; -static ev_prepare prepare_ev; +static ev_idle iw; +static ev_prepare pw; static struct timeval tv_now; static void @@ -208,17 +224,28 @@ ev_tstamp t = ev_now (); tv_now.tv_sec = (long)t; - tv_now.tv_usec = (long)((t - (ev_tstamp)tv_now.tv_sec) * 1e-6); + tv_now.tv_usec = (long)((t - (ev_tstamp)tv_now.tv_sec) * 1e6); +} + +static void +idle_cb (EV_P_ ev_idle *w, int revents) +{ + ev_idle_stop (EV_A_ w); } static void timer_cb (EV_P_ ev_timer *w, int revents) { + adns_state ads = (adns_state)w->data; + update_now (); + + adns_processtimeouts (ads, &tv_now); } static void io_cb (EV_P_ ev_io *w, int revents) { + adns_state ads = (adns_state)w->data; update_now (EV_A); if (revents & EV_READ ) adns_processreadable (ads, w->fd, &tv_now); @@ -231,6 +258,7 @@ { int i; int timeout = 3600000; + adns_state ads = (adns_state)w->data; if (ev_is_active (&tw)) { @@ -238,14 +266,16 @@ ev_timer_stop (EV_A_ &tw); } + if (ev_is_active (&iw)) + ev_idle_stop (EV_A_ &iw); + for (i = 0; i < nfd; ++i) { ev_ref (); ev_io_stop (EV_A_ iow + i); } - process (); - + process (ads); update_now (EV_A); nfd = mfd; @@ -274,6 +304,9 @@ } } +static HV *stash; +static adns_state ads; + MODULE = EV::ADNS PACKAGE = EV::ADNS PROTOTYPES: ENABLE @@ -370,12 +403,17 @@ I_EV_API ("EV::ADNS"); - ev_prepare_init (&prepare_ev, prepare_cb); ev_prepare_start (EV_DEFAULT_ &prepare_ev); + adns_init (&ads, adns_if_noenv | adns_if_noerrprint | adns_if_noserverwarn | adns_if_noautosys, 0); + + ev_prepare_init (&pw, prepare_cb); + pw.data = (void *)ads; + ev_prepare_start (EV_DEFAULT_ &pw); ev_unref (); + ev_init (&iw, idle_cb); ev_set_priority (&iw, EV_MINPRI); + iw.data = (void *)ads; ev_init (&tw, timer_cb); - - adns_init (&ads, adns_if_noenv | adns_if_noerrprint | adns_if_noserverwarn | adns_if_noautosys, 0); + tw.data = (void *)ads; } void submit (char *owner, int type, int flags, SV *cb) @@ -400,6 +438,9 @@ c->self = csv; c->cb = newSVsv (cb); + if (!ev_is_active (&iw)) + ev_idle_start (EV_A_ &iw); + if (GIMME_V != G_VOID) { csv = sv_2mortal (newRV_inc (csv));