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

Comparing EV/EV.xs (file contents):
Revision 1.1 by root, Fri Oct 26 16:50:05 2007 UTC vs.
Revision 1.10 by root, Mon Oct 29 07:56:03 2007 UTC

7 7
8#include <sys/time.h> 8#include <sys/time.h>
9#include <time.h> 9#include <time.h>
10#include <event.h> 10#include <event.h>
11#include <evdns.h> 11#include <evdns.h>
12/*include <evhttp.h>*/ /* does not compile */ 12
13/* workaround for evhttp.h requiring obscure bsd headers */
14#ifndef TAILQ_ENTRY
15#define TAILQ_ENTRY(type) \
16struct { \
17 struct type *tqe_next; /* next element */ \
18 struct type **tqe_prev; /* address of previous next element */ \
19}
20#endif /* !TAILQ_ENTRY */
21#include <evhttp.h>
13 22
14#define EV_NONE 0 23#define EV_NONE 0
15#define EV_UNDEF -1 24#define EV_UNDEF -1
16 25
17#define TIMEOUT_NONE HUGE_VAL 26#define TIMEOUT_NONE HUGE_VAL
18 27
19typedef struct event_base *Base; 28typedef struct event_base *Base;
29typedef int Signal;
20 30
21static HV *stash_base, *stash_event; 31static HV *stash_base, *stash_event;
22 32
23static double tv_get (struct timeval *tv) 33static double tv_get (struct timeval *tv)
24{ 34{
28static void tv_set (struct timeval *tv, double val) 38static void tv_set (struct timeval *tv, double val)
29{ 39{
30 tv->tv_sec = (long)val; 40 tv->tv_sec = (long)val;
31 tv->tv_usec = (long)((val - (double)tv->tv_sec) * 1e6); 41 tv->tv_usec = (long)((val - (double)tv->tv_sec) * 1e6);
32 42
43}
44
45static int
46sv_signum (SV *sig)
47{
48 int signum;
49
50 if (SvIV (sig) > 0)
51 return SvIV (sig);
52
53 for (signum = 1; signum < SIG_SIZE; ++signum)
54 if (strEQ (SvPV_nolen (sig), PL_sig_name [signum]))
55 return signum;
56
57 return -1;
33} 58}
34 59
35///////////////////////////////////////////////////////////////////////////// 60/////////////////////////////////////////////////////////////////////////////
36// Event 61// Event
37 62
56 81
57static void e_cb (int fd, short events, void *arg); 82static void e_cb (int fd, short events, void *arg);
58 83
59static int sv_fileno (SV *fh) 84static int sv_fileno (SV *fh)
60{ 85{
61 if (fh)
62 {
63 SvGETMAGIC (fh); 86 SvGETMAGIC (fh);
64 87
65 if (SvROK (fh)) 88 if (SvROK (fh))
66 fh = SvRV (fh); 89 fh = SvRV (fh);
67 90
68 if (SvTYPE (fh) == SVt_PVGV) 91 if (SvTYPE (fh) == SVt_PVGV)
69 return PerlIO_fileno (IoIFP (sv_2io (fh))); 92 return PerlIO_fileno (IoIFP (sv_2io (fh)));
70 93
71 if (SvIOK (fh)) 94 if (SvIOK (fh))
72 return SvIV (fh); 95 return SvIV (fh);
73 }
74 96
75 return -1; 97 return -1;
76} 98}
77 99
78static Event 100static Event
110 132
111 if (ev->abstime) 133 if (ev->abstime)
112 { 134 {
113 double now = e_now (); 135 double now = e_now ();
114 136
115 if (now > to && ev->interval) 137 if (ev->interval)
116 ev->timeout = (to += ceil ((now - to) / ev->interval) * ev->interval); 138 ev->timeout = (to += ceil ((now - to) / ev->interval) * ev->interval);
117 139
118 to -= now; 140 to -= now;
119 } 141 }
120 else if (to < 0.) 142 else if (to < 0.)
163 dSP; 185 dSP;
164 186
165 ENTER; 187 ENTER;
166 SAVETMPS; 188 SAVETMPS;
167 189
168 if (!(ev->ev.ev_events & EV_PERSIST)) 190 if (!(ev->ev.ev_events & EV_PERSIST) || (events & EV_TIMEOUT))
169 ev->active = 0; 191 ev->active = 0;
170 192
171 PUSHMARK (SP); 193 PUSHMARK (SP);
172 EXTEND (SP, 2); 194 EXTEND (SP, 2);
173 PUSHs (sv_2mortal (e_self (ev))); 195 PUSHs (sv_2mortal (e_self (ev)));
174 PUSHs (sv_2mortal (newSViv (events))); 196 PUSHs (sv_2mortal (newSViv (events)));
175 PUTBACK; 197 PUTBACK;
176 call_sv (ev->cb, G_DISCARD | G_VOID | G_EVAL); 198 call_sv (ev->cb, G_DISCARD | G_VOID | G_EVAL);
177 /*TODO: if err, call some logging function */
178 199
179 if (ev->interval && !ev->active) 200 if (ev->interval && !ev->active)
180 e_start (ev); 201 e_start (ev);
181 202
182 FREETMPS; 203 FREETMPS;
204
205 if (SvTRUE (ERRSV))
206 {
207 PUSHMARK (SP);
208 PUTBACK;
209 call_sv (get_sv ("EV::DIED", 1), G_DISCARD | G_VOID | G_EVAL | G_KEEPERR);
210 }
211
183 LEAVE; 212 LEAVE;
184} 213}
185 214
186///////////////////////////////////////////////////////////////////////////// 215/////////////////////////////////////////////////////////////////////////////
187// DNS 216// DNS
222 251
223 PUTBACK; 252 PUTBACK;
224 call_sv (sv_2mortal (cb), G_DISCARD | G_VOID | G_EVAL); 253 call_sv (sv_2mortal (cb), G_DISCARD | G_VOID | G_EVAL);
225 254
226 FREETMPS; 255 FREETMPS;
256
257 if (SvTRUE (ERRSV))
258 {
259 PUSHMARK (SP);
260 PUTBACK;
261 call_sv (get_sv ("EV::DIED", 1), G_DISCARD | G_VOID | G_EVAL | G_KEEPERR);
262 }
263
227 LEAVE; 264 LEAVE;
228} 265}
229 266
230///////////////////////////////////////////////////////////////////////////// 267/////////////////////////////////////////////////////////////////////////////
231// XS interface functions 268// XS interface functions
232 269
233MODULE = EV PACKAGE = EV PREFIX = event_ 270MODULE = EV PACKAGE = EV PREFIX = event_
234 271
235BOOT: 272BOOT:
236{ 273{
274 int i;
237 HV *stash = gv_stashpv ("EV", 1); 275 HV *stash = gv_stashpv ("EV", 1);
238 276
239 static const struct { 277 static const struct {
240 const char *name; 278 const char *name;
241 IV iv; 279 IV iv;
283 321
284int event_dispatch () 322int event_dispatch ()
285 323
286int event_loop (int flags = 0) 324int event_loop (int flags = 0)
287 325
288int event_loopexit (double after) 326int event_loopexit (double after = 0)
289 CODE: 327 CODE:
290{ 328{
291 struct timeval tv; 329 struct timeval tv;
292 tv_set (&tv, after); 330 tv_set (&tv, after);
293 event_loopexit (&tv); 331 event_loopexit (&tv);
294} 332}
295 333
296Event event (SV *cb) 334Event event (SV *cb)
297 CODE: 335 CODE:
298 RETVAL = e_new (0, 0, cb); 336 RETVAL = e_new (NEWSV (0, 0), 0, cb);
299 OUTPUT: 337 OUTPUT:
300 RETVAL 338 RETVAL
301 339
302Event io (SV *fh, short events, SV *cb) 340Event io (SV *fh, short events, SV *cb)
303 ALIAS: 341 ALIAS:
306 RETVAL = e_new (fh, events, cb); 344 RETVAL = e_new (fh, events, cb);
307 if (!ix) e_start (RETVAL); 345 if (!ix) e_start (RETVAL);
308 OUTPUT: 346 OUTPUT:
309 RETVAL 347 RETVAL
310 348
349Event timed_io (SV *fh, short events, double timeout, SV *cb)
350 ALIAS:
351 timed_io_ns = 1
352 CODE:
353{
354 events = timeout ? events & ~EV_PERSIST : events | EV_PERSIST;
355
356 RETVAL = e_new (fh, events, cb);
357
358 if (timeout)
359 {
360 RETVAL->timeout = timeout;
361 RETVAL->interval = 1;
362 }
363
364 if (!ix) e_start (RETVAL);
365}
366 OUTPUT:
367 RETVAL
368
311Event timer (double after, int repeat, SV *cb) 369Event timer (double after, int repeat, SV *cb)
312 ALIAS: 370 ALIAS:
313 timer_ns = 1 371 timer_ns = 1
314 CODE: 372 CODE:
315 RETVAL = e_new (0, 0, cb); 373 RETVAL = e_new (NEWSV (0, 0), 0, cb);
316 RETVAL->timeout = after; 374 RETVAL->timeout = after;
317 RETVAL->interval = repeat; 375 RETVAL->interval = repeat;
318 if (!ix) e_start (RETVAL); 376 if (!ix) e_start (RETVAL);
319 OUTPUT: 377 OUTPUT:
320 RETVAL 378 RETVAL
321 379
322Event timer_abs (double at, double interval, SV *cb) 380Event timer_abs (double at, double interval, SV *cb)
323 ALIAS: 381 ALIAS:
324 timer_abs_ns = 1 382 timer_abs_ns = 1
325 CODE: 383 CODE:
326 RETVAL = e_new (0, 0, cb); 384 RETVAL = e_new (NEWSV (0, 0), 0, cb);
327 RETVAL->timeout = at; 385 RETVAL->timeout = at;
328 RETVAL->interval = interval; 386 RETVAL->interval = interval;
329 RETVAL->abstime = 1; 387 RETVAL->abstime = 1;
330 if (!ix) e_start (RETVAL); 388 if (!ix) e_start (RETVAL);
331 OUTPUT: 389 OUTPUT:
332 RETVAL 390 RETVAL
333 391
334Event signal (SV *signal, SV *cb) 392Event signal (Signal signum, SV *cb)
335 ALIAS: 393 ALIAS:
336 signal_ns = 1 394 signal_ns = 1
337 CODE: 395 CODE:
338 RETVAL = e_new (signal, EV_SIGNAL | EV_PERSIST, cb); 396 RETVAL = e_new (ST (0), EV_SIGNAL | EV_PERSIST, cb);
397 RETVAL->ev.ev_fd = signum;
339 if (!ix) e_start (RETVAL); 398 if (!ix) e_start (RETVAL);
340 OUTPUT: 399 OUTPUT:
341 RETVAL 400 RETVAL
342 401
343PROTOTYPES: DISABLE 402PROTOTYPES: DISABLE
405 CODE: 464 CODE:
406 e_stop (ev); 465 e_stop (ev);
407 SvREFCNT_dec (ev->cb); 466 SvREFCNT_dec (ev->cb);
408 SvREFCNT_dec (ev->fh); 467 SvREFCNT_dec (ev->fh);
409 468
410void cb (Event ev, SV *new_cb) 469SV *cb (Event ev, SV *new_cb = 0)
411 CODE: 470 CODE:
471 RETVAL = newSVsv (ev->cb);
472 if (items > 1)
412 sv_setsv (ev->cb, new_cb); 473 sv_setsv (ev->cb, new_cb);
474 OUTPUT:
475 RETVAL
413 476
414SV *fh (Event ev, SV *new_fh = 0) 477SV *fh (Event ev, SV *new_fh = 0)
415 ALIAS:
416 signal = 0
417 CODE: 478 CODE:
418 RETVAL = newSVsv (ev->fh); 479 RETVAL = newSVsv (ev->fh);
419 if (items > 1) 480 if (items > 1)
420 { 481 {
421 if (ev->active) event_del (&ev->ev); 482 if (ev->active) event_del (&ev->ev);
422 sv_setsv (ev->fh, new_fh); 483 sv_setsv (ev->fh, new_fh);
423 ev->ev.ev_fd = e_fd (ev); 484 ev->ev.ev_fd = sv_fileno (ev->fh);
485 ev->ev.ev_events &= ev->ev.ev_events & ~EV_SIGNAL;
424 if (ev->active) event_add (&ev->ev, e_tv (ev)); 486 if (ev->active) event_add (&ev->ev, e_tv (ev));
425 } 487 }
488 OUTPUT:
489 RETVAL
490
491SV *signal (Event ev, SV *new_signal = 0)
492 CODE:
493{
494 Signal signum;
495
496 if (items > 1)
497 signum = sv_signum (new_signal); /* may croak here */
498
499 RETVAL = newSVsv (ev->fh);
500
501 if (items > 1)
502 {
503 if (ev->active) event_del (&ev->ev);
504 sv_setsv (ev->fh, new_signal);
505 ev->ev.ev_fd = signum;
506 ev->ev.ev_events |= EV_SIGNAL;
507 if (ev->active) event_add (&ev->ev, e_tv (ev));
508 }
509}
426 OUTPUT: 510 OUTPUT:
427 RETVAL 511 RETVAL
428 512
429short events (Event ev, short new_events = EV_UNDEF) 513short events (Event ev, short new_events = EV_UNDEF)
430 CODE: 514 CODE:
470 static const struct { 554 static const struct {
471 const char *name; 555 const char *name;
472 IV iv; 556 IV iv;
473 } *civ, const_iv[] = { 557 } *civ, const_iv[] = {
474# define const_iv(pfx, name) { # name, (IV) pfx ## name }, 558# define const_iv(pfx, name) { # name, (IV) pfx ## name },
475
476 const_iv (DNS_, ERR_NONE) 559 const_iv (DNS_, ERR_NONE)
477 const_iv (DNS_, ERR_FORMAT) 560 const_iv (DNS_, ERR_FORMAT)
478 const_iv (DNS_, ERR_SERVERFAILED) 561 const_iv (DNS_, ERR_SERVERFAILED)
479 const_iv (DNS_, ERR_NOTEXIST) 562 const_iv (DNS_, ERR_NOTEXIST)
480 const_iv (DNS_, ERR_NOTIMPL) 563 const_iv (DNS_, ERR_NOTIMPL)
526 CODE: 609 CODE:
527{ 610{
528 STRLEN len; 611 STRLEN len;
529 char *data = SvPVbyte (addr, len); 612 char *data = SvPVbyte (addr, len);
530 if (len != (ix ? 16 : 4)) 613 if (len != (ix ? 16 : 4))
531 croak ("ipv4/ipv6 address to resolve must be given as 4/16 byte octet string"); 614 croak ("ipv4/ipv6 address to be resolved must be given as 4/16 byte octet string");
532 615
533 RETVAL = ix 616 RETVAL = ix
534 ? evdns_resolve_reverse_ipv6 ((struct in6_addr *)data, flags, dns_cb, (void *)SvREFCNT_inc (cb)) 617 ? evdns_resolve_reverse_ipv6 ((struct in6_addr *)data, flags, dns_cb, (void *)SvREFCNT_inc (cb))
535 : evdns_resolve_reverse ((struct in_addr *)data, flags, dns_cb, (void *)SvREFCNT_inc (cb)); 618 : evdns_resolve_reverse ((struct in_addr *)data, flags, dns_cb, (void *)SvREFCNT_inc (cb));
536} 619}
551 634
552void evdns_search_add (char *domain) 635void evdns_search_add (char *domain)
553 636
554void evdns_search_ndots_set (int ndots) 637void evdns_search_ndots_set (int ndots)
555 638
639
640MODULE = EV PACKAGE = EV::HTTP PREFIX = evhttp_
641
642BOOT:
643{
644 HV *stash = gv_stashpv ("EV::HTTP", 1);
645
646 static const struct {
647 const char *name;
648 IV iv;
649 } *civ, const_iv[] = {
650# define const_iv(pfx, name) { # name, (IV) pfx ## name },
651 const_iv (HTTP_, OK)
652 const_iv (HTTP_, NOCONTENT)
653 const_iv (HTTP_, MOVEPERM)
654 const_iv (HTTP_, MOVETEMP)
655 const_iv (HTTP_, NOTMODIFIED)
656 const_iv (HTTP_, BADREQUEST)
657 const_iv (HTTP_, NOTFOUND)
658 const_iv (HTTP_, SERVUNAVAIL)
659 const_iv (EVHTTP_, REQ_OWN_CONNECTION)
660 const_iv (EVHTTP_, PROXY_REQUEST)
661 const_iv (EVHTTP_, REQ_GET)
662 const_iv (EVHTTP_, REQ_POST)
663 const_iv (EVHTTP_, REQ_HEAD)
664 const_iv (EVHTTP_, REQUEST)
665 const_iv (EVHTTP_, RESPONSE)
666 };
667
668 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; )
669 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv));
670}
671
672MODULE = EV PACKAGE = EV::HTTP::Request PREFIX = evhttp_request_
673
674#HttpRequest new (SV *klass, SV *cb)
675
676#void DESTROY (struct evhttp_request *req);
677
678
679
680
681
682
683
684

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines