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.8 by root, Sat Dec 1 21:29:08 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 HV *stash; 10static struct pollfd *fds;
11static adns_state ads; 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}
12 31
13struct ctx 32struct ctx
14{ 33{
15 SV *self; 34 SV *self;
35 adns_state ads;
16 adns_query query; 36 adns_query query;
17 SV *cb; 37 SV *cb;
18}; 38};
19 39
20static SV * 40static SV *
26 46
27 return newRV_noinc ((SV *)av); 47 return newRV_noinc ((SV *)av);
28} 48}
29 49
30static void 50static void
31process () 51process (adns_state ads)
32{ 52{
33 dSP; 53 dSP;
34 54
35 for (;;) 55 for (;;)
36 { 56 {
45 if (r) 65 if (r)
46 break; 66 break;
47 67
48 c = (struct ctx *)ctx; 68 c = (struct ctx *)ctx;
49 cb = c->cb; 69 cb = c->cb;
50 c->cb = 0; 70 c->cb = 0; outstanding_dec (ads);
51 ev_unref ();
52 SvREFCNT_dec (c->self); 71 SvREFCNT_dec (c->self);
72
73 assert (cb);
53 74
54 PUSHMARK (SP); 75 PUSHMARK (SP);
55 76
56 EXTEND (SP, a->nrrs + 2); 77 EXTEND (SP, a->nrrs + 2);
57 PUSHs (sv_2mortal (newSViv (a->status))); 78 PUSHs (sv_2mortal (newSViv (a->status)));
207 228
208 PUTBACK; 229 PUTBACK;
209 call_sv (cb, G_VOID | G_DISCARD | G_EVAL); 230 call_sv (cb, G_VOID | G_DISCARD | G_EVAL);
210 SPAGAIN; 231 SPAGAIN;
211 232
233 if (SvTRUE (ERRSV))
234 warn ("%s", SvPV_nolen (ERRSV));
235
212 SvREFCNT_dec (cb); 236 SvREFCNT_dec (cb);
213 } 237 }
214} 238}
215 239
216static struct pollfd *fds;
217static int nfd, mfd;
218static ev_io *iow;
219static ev_timer tw;
220static ev_prepare prepare_ev;
221static struct timeval tv_now;
222
223static void 240static void
224update_now (EV_P) 241update_now (EV_P)
225{ 242{
226 ev_tstamp t = ev_now (); 243 ev_tstamp t = ev_now (EV_A);
227 244
228 tv_now.tv_sec = (long)t; 245 tv_now.tv_sec = (long)t;
229 tv_now.tv_usec = (long)((t - (ev_tstamp)tv_now.tv_sec) * 1e-6); 246 tv_now.tv_usec = (long)((t - (ev_tstamp)tv_now.tv_sec) * 1e6);
247}
248
249static void
250idle_cb (EV_P_ ev_idle *w, int revents)
251{
252 ev_idle_stop (EV_A, w);
230} 253}
231 254
232static void 255static void
233timer_cb (EV_P_ ev_timer *w, int revents) 256timer_cb (EV_P_ ev_timer *w, int revents)
234{ 257{
258 adns_state ads = (adns_state)w->data;
259 update_now (EV_A);
260
261 adns_processtimeouts (ads, &tv_now);
235} 262}
236 263
237static void 264static void
238io_cb (EV_P_ ev_io *w, int revents) 265io_cb (EV_P_ ev_io *w, int revents)
239{ 266{
267 adns_state ads = (adns_state)w->data;
240 update_now (EV_A); 268 update_now (EV_A);
241 269
242 if (revents & EV_READ ) adns_processreadable (ads, w->fd, &tv_now); 270 if (revents & EV_READ ) adns_processreadable (ads, w->fd, &tv_now);
243 if (revents & EV_WRITE) adns_processwriteable (ads, w->fd, &tv_now); 271 if (revents & EV_WRITE) adns_processwriteable (ads, w->fd, &tv_now);
244} 272}
247static void 275static void
248prepare_cb (EV_P_ ev_prepare *w, int revents) 276prepare_cb (EV_P_ ev_prepare *w, int revents)
249{ 277{
250 int i; 278 int i;
251 int timeout = 3600000; 279 int timeout = 3600000;
280 adns_state ads = (adns_state)w->data;
252 281
253 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)
254 { 294 {
255 ev_ref ();
256 ev_timer_stop (EV_A_ &tw); 295 ev_prepare_stop (EV_A, w);
296 return;
257 } 297 }
258
259 for (i = 0; i < nfd; ++i)
260 {
261 ev_ref ();
262 ev_io_stop (EV_A_ iow + i);
263 }
264
265 process ();
266 298
267 update_now (EV_A); 299 update_now (EV_A);
268 300
269 nfd = mfd; 301 nfd = mfd;
270 302
275 free (iow); iow = malloc (mfd * sizeof (ev_io)); 307 free (iow); iow = malloc (mfd * sizeof (ev_io));
276 free (fds); fds = malloc (mfd * sizeof (struct pollfd)); 308 free (fds); fds = malloc (mfd * sizeof (struct pollfd));
277 } 309 }
278 310
279 ev_timer_set (&tw, timeout * 1e-3, 0.); 311 ev_timer_set (&tw, timeout * 1e-3, 0.);
280 ev_timer_start (EV_A_ &tw); 312 ev_timer_start (EV_A, &tw);
281 ev_unref ();
282 313
283 // create one ev_io per pollfd 314 // create one ev_io per pollfd
284 for (i = 0; i < nfd; ++i) 315 for (i = 0; i < nfd; ++i)
285 { 316 {
317 ev_io *w = iow + i;
318
286 ev_io_init (iow + i, io_cb, fds [i].fd, 319 ev_io_init (w, io_cb, fds [i].fd,
287 ((fds [i].events & POLLIN ? EV_READ : 0) 320 ((fds [i].events & POLLIN ? EV_READ : 0)
288 | (fds [i].events & POLLOUT ? EV_WRITE : 0))); 321 | (fds [i].events & POLLOUT ? EV_WRITE : 0)));
289 322
323 w->data = (void *)ads;
290 ev_io_start (EV_A_ iow + i); 324 ev_io_start (EV_A, w);
291 ev_unref ();
292 } 325 }
293} 326}
327
328static HV *stash;
329static adns_state ads;
294 330
295MODULE = EV::ADNS PACKAGE = EV::ADNS 331MODULE = EV::ADNS PACKAGE = EV::ADNS
296 332
297PROTOTYPES: ENABLE 333PROTOTYPES: ENABLE
298 334
386 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; ) 422 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; )
387 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv)); 423 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv));
388 424
389 I_EV_API ("EV::ADNS"); 425 I_EV_API ("EV::ADNS");
390 426
391 ev_prepare_init (&prepare_ev, prepare_cb); ev_prepare_start (EV_DEFAULT_ &prepare_ev); 427 adns_init (&ads, adns_if_noenv | adns_if_noerrprint | adns_if_noserverwarn | adns_if_noautosys, 0);
392 ev_unref ();
393 428
429 ev_prepare_init (&pw, prepare_cb);
430 pw.data = (void *)ads;
431
432 ev_init (&iw, idle_cb); ev_set_priority (&iw, EV_MINPRI);
433 iw.data = (void *)ads;
394 ev_init (&tw, timer_cb); 434 ev_init (&tw, timer_cb);
395 435 tw.data = (void *)ads;
396 adns_init (&ads, adns_if_noenv | adns_if_noerrprint | adns_if_noserverwarn | adns_if_noautosys, 0);
397} 436}
398 437
399void submit (char *owner, int type, int flags, SV *cb) 438void submit (char *owner, int type, int flags, SV *cb)
400 PPCODE: 439 PPCODE:
401{ 440{
402 SV *csv = NEWSV (0, sizeof (struct ctx)); 441 SV *csv = NEWSV (0, sizeof (struct ctx));
403 struct ctx *c = (struct ctx *)SvPVX (csv); 442 struct ctx *c = (struct ctx *)SvPVX (csv);
404 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);
405 446
406 if (r) 447 if (r)
407 { 448 {
408 SvREFCNT_dec (csv); 449 SvREFCNT_dec (csv);
409 errno = r; 450 errno = r;
410 XSRETURN_EMPTY; 451 XSRETURN_EMPTY;
411 } 452 }
412 else 453 else
413 { 454 {
414 ev_ref ();
415 SvPOK_only (csv); 455 SvPOK_only (csv);
416 SvCUR_set (csv, sizeof (struct ctx)); 456 SvCUR_set (csv, sizeof (struct ctx));
417 457
418 c->self = csv; 458 c->self = csv;
419 c->cb = newSVsv (cb); 459 c->cb = newSVsv (cb);
460 c->ads = ads;
461
462 if (!ev_is_active (&iw))
463 ev_idle_start (EV_DEFAULT, &iw);
420 464
421 if (GIMME_V != G_VOID) 465 if (GIMME_V != G_VOID)
422 { 466 {
423 csv = sv_2mortal (newRV_inc (csv)); 467 csv = sv_2mortal (newRV_inc (csv));
424 sv_bless (csv, stash); 468 sv_bless (csv, stash);
440 484
441 c = (struct ctx *)SvPVX (SvRV (req)); 485 c = (struct ctx *)SvPVX (SvRV (req));
442 486
443 if (c->cb) 487 if (c->cb)
444 { 488 {
445 ev_unref ();
446 SvREFCNT_dec (c->cb); 489 SvREFCNT_dec (c->cb);
447 c->cb = 0; 490 c->cb = 0; outstanding_dec (c->ads);
448 adns_cancel (c->query); 491 adns_cancel (c->query);
449 SvREFCNT_dec (c->self); 492 SvREFCNT_dec (c->self);
450 } 493 }
451} 494}
452 495

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines