ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/EV-ADNS/ADNS.xs
(Generate patch)

Comparing cvsroot/EV-ADNS/ADNS.xs (file contents):
Revision 1.14 by root, Sat Dec 8 22:35:31 2007 UTC vs.
Revision 1.16 by root, Thu Dec 20 07:13:36 2007 UTC

5#include <poll.h> 5#include <poll.h>
6#include <adns.h> 6#include <adns.h>
7 7
8#include "EVAPI.h" 8#include "EVAPI.h"
9 9
10static struct pollfd *fds;
11static int nfd, mfd;
12static ev_io *iow;
13static ev_timer tw;
14static ev_idle iw;
15static ev_prepare pw;
16static struct timeval tv_now;
17static int outstanding;
18
19static void
20outstanding_inc (adns_state ads)
21{
22 if (!outstanding++)
23 ev_prepare_start (EV_DEFAULT, &pw);
24}
25
26static void
27outstanding_dec (adns_state ads)
28{
29 --outstanding;
30}
31
10struct ctx 32struct ctx
11{ 33{
12 SV *self; 34 SV *self;
35 adns_state ads;
13 adns_query query; 36 adns_query query;
14 SV *cb; 37 SV *cb;
15}; 38};
16 39
17static SV * 40static SV *
42 if (r) 65 if (r)
43 break; 66 break;
44 67
45 c = (struct ctx *)ctx; 68 c = (struct ctx *)ctx;
46 cb = c->cb; 69 cb = c->cb;
47 c->cb = 0; 70 c->cb = 0; outstanding_dec (ads);
48 ev_unref (EV_A);
49 SvREFCNT_dec (c->self); 71 SvREFCNT_dec (c->self);
72
73 assert (cb);
50 74
51 PUSHMARK (SP); 75 PUSHMARK (SP);
52 76
53 EXTEND (SP, a->nrrs + 2); 77 EXTEND (SP, a->nrrs + 2);
54 PUSHs (sv_2mortal (newSViv (a->status))); 78 PUSHs (sv_2mortal (newSViv (a->status)));
204 228
205 PUTBACK; 229 PUTBACK;
206 call_sv (cb, G_VOID | G_DISCARD | G_EVAL); 230 call_sv (cb, G_VOID | G_DISCARD | G_EVAL);
207 SPAGAIN; 231 SPAGAIN;
208 232
233 if (SvTRUE (ERRSV))
234 warn ("%s", SvPV_nolen (ERRSV));
235
209 SvREFCNT_dec (cb); 236 SvREFCNT_dec (cb);
210 } 237 }
211} 238}
212 239
213static struct pollfd *fds;
214static int nfd, mfd;
215static ev_io *iow;
216static ev_timer tw;
217static ev_idle iw;
218static ev_prepare pw;
219static struct timeval tv_now;
220
221static void 240static void
222update_now (EV_P) 241update_now (EV_P)
223{ 242{
224 ev_tstamp t = ev_now (EV_A); 243 ev_tstamp t = ev_now (EV_A);
225 244
228} 247}
229 248
230static void 249static void
231idle_cb (EV_P_ ev_idle *w, int revents) 250idle_cb (EV_P_ ev_idle *w, int revents)
232{ 251{
233 ev_idle_stop (EV_A_ w); 252 ev_idle_stop (EV_A, w);
234} 253}
235 254
236static void 255static void
237timer_cb (EV_P_ ev_timer *w, int revents) 256timer_cb (EV_P_ ev_timer *w, int revents)
238{ 257{
259 int i; 278 int i;
260 int timeout = 3600000; 279 int timeout = 3600000;
261 adns_state ads = (adns_state)w->data; 280 adns_state ads = (adns_state)w->data;
262 281
263 if (ev_is_active (&tw)) 282 if (ev_is_active (&tw))
283 ev_timer_stop (EV_A, &tw);
284
285 if (ev_is_active (&iw))
286 ev_idle_stop (EV_A, &iw);
287
288 for (i = 0; i < nfd; ++i)
289 ev_io_stop (EV_A, iow + i);
290
291 process (ads);
292
293 if (!outstanding)
264 { 294 {
265 ev_ref (EV_A);
266 ev_timer_stop (EV_A_ &tw); 295 ev_prepare_stop (EV_A, w);
296 return;
267 } 297 }
268 298
269 if (ev_is_active (&iw))
270 ev_idle_stop (EV_A_ &iw);
271
272 for (i = 0; i < nfd; ++i)
273 {
274 ev_ref (EV_A);
275 ev_io_stop (EV_A_ iow + i);
276 }
277
278 process (ads);
279 update_now (EV_A); 299 update_now (EV_A);
280 300
281 nfd = mfd; 301 nfd = mfd;
282 302
283 while (adns_beforepoll (ads, fds, &nfd, &timeout, &tv_now)) 303 while (adns_beforepoll (ads, fds, &nfd, &timeout, &tv_now))
287 free (iow); iow = malloc (mfd * sizeof (ev_io)); 307 free (iow); iow = malloc (mfd * sizeof (ev_io));
288 free (fds); fds = malloc (mfd * sizeof (struct pollfd)); 308 free (fds); fds = malloc (mfd * sizeof (struct pollfd));
289 } 309 }
290 310
291 ev_timer_set (&tw, timeout * 1e-3, 0.); 311 ev_timer_set (&tw, timeout * 1e-3, 0.);
292 ev_timer_start (EV_A_ &tw); 312 ev_timer_start (EV_A, &tw);
293 ev_unref (EV_A);
294 313
295 // create one ev_io per pollfd 314 // create one ev_io per pollfd
296 for (i = 0; i < nfd; ++i) 315 for (i = 0; i < nfd; ++i)
297 { 316 {
298 ev_io *w = iow + i; 317 ev_io *w = iow + i;
300 ev_io_init (w, io_cb, fds [i].fd, 319 ev_io_init (w, io_cb, fds [i].fd,
301 ((fds [i].events & POLLIN ? EV_READ : 0) 320 ((fds [i].events & POLLIN ? EV_READ : 0)
302 | (fds [i].events & POLLOUT ? EV_WRITE : 0))); 321 | (fds [i].events & POLLOUT ? EV_WRITE : 0)));
303 322
304 w->data = (void *)ads; 323 w->data = (void *)ads;
305 ev_io_start (EV_A_ w); 324 ev_io_start (EV_A, w);
306 ev_unref (EV_A);
307 } 325 }
308} 326}
309 327
310static HV *stash; 328static HV *stash;
311static adns_state ads; 329static adns_state ads;
408 426
409 adns_init (&ads, adns_if_noenv | adns_if_noerrprint | adns_if_noserverwarn | adns_if_noautosys, 0); 427 adns_init (&ads, adns_if_noenv | adns_if_noerrprint | adns_if_noserverwarn | adns_if_noautosys, 0);
410 428
411 ev_prepare_init (&pw, prepare_cb); 429 ev_prepare_init (&pw, prepare_cb);
412 pw.data = (void *)ads; 430 pw.data = (void *)ads;
413 ev_prepare_start (EV_DEFAULT_ &pw);
414 ev_unref (EV_A);
415 431
416 ev_init (&iw, idle_cb); ev_set_priority (&iw, EV_MINPRI); 432 ev_init (&iw, idle_cb); ev_set_priority (&iw, EV_MINPRI);
417 iw.data = (void *)ads; 433 iw.data = (void *)ads;
418 ev_init (&tw, timer_cb); 434 ev_init (&tw, timer_cb);
419 tw.data = (void *)ads; 435 tw.data = (void *)ads;
423 PPCODE: 439 PPCODE:
424{ 440{
425 SV *csv = NEWSV (0, sizeof (struct ctx)); 441 SV *csv = NEWSV (0, sizeof (struct ctx));
426 struct ctx *c = (struct ctx *)SvPVX (csv); 442 struct ctx *c = (struct ctx *)SvPVX (csv);
427 int r = adns_submit (ads, owner, type, flags, (void *)c, &c->query); 443 int r = adns_submit (ads, owner, type, flags, (void *)c, &c->query);
444
445 outstanding_inc (ads);
428 446
429 if (r) 447 if (r)
430 { 448 {
431 SvREFCNT_dec (csv); 449 SvREFCNT_dec (csv);
432 errno = r; 450 errno = r;
433 XSRETURN_EMPTY; 451 XSRETURN_EMPTY;
434 } 452 }
435 else 453 else
436 { 454 {
437 ev_ref (EV_A);
438 SvPOK_only (csv); 455 SvPOK_only (csv);
439 SvCUR_set (csv, sizeof (struct ctx)); 456 SvCUR_set (csv, sizeof (struct ctx));
440 457
441 c->self = csv; 458 c->self = csv;
442 c->cb = newSVsv (cb); 459 c->cb = newSVsv (cb);
460 c->ads = ads;
443 461
444 if (!ev_is_active (&iw)) 462 if (!ev_is_active (&iw))
445 ev_idle_start (EV_A_ &iw); 463 ev_idle_start (EV_DEFAULT, &iw);
446 464
447 if (GIMME_V != G_VOID) 465 if (GIMME_V != G_VOID)
448 { 466 {
449 csv = sv_2mortal (newRV_inc (csv)); 467 csv = sv_2mortal (newRV_inc (csv));
450 sv_bless (csv, stash); 468 sv_bless (csv, stash);
466 484
467 c = (struct ctx *)SvPVX (SvRV (req)); 485 c = (struct ctx *)SvPVX (SvRV (req));
468 486
469 if (c->cb) 487 if (c->cb)
470 { 488 {
471 ev_unref (EV_A);
472 SvREFCNT_dec (c->cb); 489 SvREFCNT_dec (c->cb);
473 c->cb = 0; 490 c->cb = 0; outstanding_dec (c->ads);
474 adns_cancel (c->query); 491 adns_cancel (c->query);
475 SvREFCNT_dec (c->self); 492 SvREFCNT_dec (c->self);
476 } 493 }
477} 494}
478 495

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines