--- cvsroot/EV-ADNS/ADNS.xs 2007/12/08 02:58:38 1.13 +++ cvsroot/EV-ADNS/ADNS.xs 2007/12/20 07:13:36 1.16 @@ -7,9 +7,32 @@ #include "EVAPI.h" +static struct pollfd *fds; +static int nfd, mfd; +static ev_io *iow; +static ev_timer tw; +static ev_idle iw; +static ev_prepare pw; +static struct timeval tv_now; +static int outstanding; + +static void +outstanding_inc (adns_state ads) +{ + if (!outstanding++) + ev_prepare_start (EV_DEFAULT, &pw); +} + +static void +outstanding_dec (adns_state ads) +{ + --outstanding; +} + struct ctx { SV *self; + adns_state ads; adns_query query; SV *cb; }; @@ -44,10 +67,11 @@ c = (struct ctx *)ctx; cb = c->cb; - c->cb = 0; - ev_unref (EV_A); + c->cb = 0; outstanding_dec (ads); SvREFCNT_dec (c->self); + assert (cb); + PUSHMARK (SP); EXTEND (SP, a->nrrs + 2); @@ -206,18 +230,13 @@ call_sv (cb, G_VOID | G_DISCARD | G_EVAL); SPAGAIN; + if (SvTRUE (ERRSV)) + warn ("%s", SvPV_nolen (ERRSV)); + SvREFCNT_dec (cb); } } -static struct pollfd *fds; -static int nfd, mfd; -static ev_io *iow; -static ev_timer tw; -static ev_idle iw; -static ev_prepare pw; -static struct timeval tv_now; - static void update_now (EV_P) { @@ -230,7 +249,7 @@ static void idle_cb (EV_P_ ev_idle *w, int revents) { - ev_idle_stop (EV_A_ w); + ev_idle_stop (EV_A, w); } static void @@ -261,21 +280,22 @@ adns_state ads = (adns_state)w->data; if (ev_is_active (&tw)) - { - ev_ref (EV_A); - ev_timer_stop (EV_A_ &tw); - } + ev_timer_stop (EV_A, &tw); if (ev_is_active (&iw)) - ev_idle_stop (EV_A_ &iw); + ev_idle_stop (EV_A, &iw); for (i = 0; i < nfd; ++i) + ev_io_stop (EV_A, iow + i); + + process (ads); + + if (!outstanding) { - ev_ref (EV_A); - ev_io_stop (EV_A_ iow + i); + ev_prepare_stop (EV_A, w); + return; } - process (ads); update_now (EV_A); nfd = mfd; @@ -289,18 +309,19 @@ } ev_timer_set (&tw, timeout * 1e-3, 0.); - ev_timer_start (EV_A_ &tw); - ev_unref (EV_A); + ev_timer_start (EV_A, &tw); // create one ev_io per pollfd for (i = 0; i < nfd; ++i) { - ev_io_init (iow + i, io_cb, fds [i].fd, + ev_io *w = iow + i; + + ev_io_init (w, io_cb, fds [i].fd, ((fds [i].events & POLLIN ? EV_READ : 0) | (fds [i].events & POLLOUT ? EV_WRITE : 0))); - ev_io_start (EV_A_ iow + i); - ev_unref (EV_A); + w->data = (void *)ads; + ev_io_start (EV_A, w); } } @@ -407,8 +428,6 @@ ev_prepare_init (&pw, prepare_cb); pw.data = (void *)ads; - ev_prepare_start (EV_DEFAULT_ &pw); - ev_unref (EV_A); ev_init (&iw, idle_cb); ev_set_priority (&iw, EV_MINPRI); iw.data = (void *)ads; @@ -423,6 +442,8 @@ struct ctx *c = (struct ctx *)SvPVX (csv); int r = adns_submit (ads, owner, type, flags, (void *)c, &c->query); + outstanding_inc (ads); + if (r) { SvREFCNT_dec (csv); @@ -431,15 +452,15 @@ } else { - ev_ref (EV_A); SvPOK_only (csv); SvCUR_set (csv, sizeof (struct ctx)); c->self = csv; c->cb = newSVsv (cb); + c->ads = ads; if (!ev_is_active (&iw)) - ev_idle_start (EV_A_ &iw); + ev_idle_start (EV_DEFAULT, &iw); if (GIMME_V != G_VOID) { @@ -465,9 +486,8 @@ if (c->cb) { - ev_unref (EV_A); SvREFCNT_dec (c->cb); - c->cb = 0; + c->cb = 0; outstanding_dec (c->ads); adns_cancel (c->query); SvREFCNT_dec (c->self); }