File Coverage

Event.xs
Criterion Covered Total %
statement 227 334 67.9
branch 104 222 46.8
condition n/a
subroutine n/a
pod n/a
total 331 556 59.5


line stmt bran cond sub pod time code
1             /* -*- C -*- sometimes */
2              
3             #define MIN_PERL_DEFINE 1
4              
5             #ifdef __cplusplus
6             extern "C" {
7             #endif
8              
9             #include
10             #include
11             #include
12              
13             #ifdef __cplusplus
14             }
15             #endif
16              
17             #include "ppport.h"
18              
19             /* lexical warnings -- waiting for appropriate magic from
20             paul.marquess@bt.com */
21             #if 0
22             static void Event_warn(const char* pat, ...) {
23             dTHX;
24             va_list args;
25             va_start(args, pat);
26             if (!ckWARN_d(WARN_ALL))
27             return;
28             Perl_vwarner(aTHX_ WARN_ALL, pat, &args);
29             va_end(args);
30             }
31              
32             # undef warn
33             # define warn Event_warn
34             #endif
35              
36             #if 1
37             #ifdef warn
38             # undef warn
39             #endif
40             #define warn Event_warn
41              
42 5           static void Event_warn(const char* pat, ...) {
43             STRLEN n_a;
44 5           dSP;
45             SV *msg;
46             va_list args;
47             /* perl_require_pv("Carp.pm"); Couldn't possibly be unloaded.*/
48 5           va_start(args, pat);
49 5           msg = sv_newmortal();
50 5           sv_vsetpvfn(msg, pat, strlen(pat), &args, Null(SV**), 0, 0);
51 5           va_end(args);
52 5           SvREADONLY_on(msg);
53 5 50         PUSHMARK(SP);
54 5 50         XPUSHs(msg);
55 5           PUTBACK;
56 5           perl_call_pv("Carp::carp", G_DISCARD);
57 5           }
58             #endif
59              
60             #ifdef croak
61             # undef croak
62             #endif
63             #define croak Event_croak
64              
65 19           static void Event_croak(const char* pat, ...) {
66             STRLEN n_a;
67 19           dSP;
68             SV *msg;
69             va_list args;
70             /* perl_require_pv("Carp.pm"); Couldn't possibly be unloaded.*/
71 19           va_start(args, pat);
72 19           msg = sv_newmortal();
73 19           sv_vsetpvfn(msg, pat, strlen(pat), &args, Null(SV**), 0, 0);
74 19           va_end(args);
75 19           SvREADONLY_on(msg);
76 19 50         PUSHMARK(SP);
77 19 50         XPUSHs(msg);
78 19           PUTBACK;
79 19           perl_call_pv("Carp::croak", G_DISCARD);
80 0           PerlIO_puts(PerlIO_stderr(), "panic: Carp::croak failed\n");
81 0           (void)PerlIO_flush(PerlIO_stderr());
82 0           my_failure_exit();
83             }
84              
85             #ifdef WIN32
86             # include
87             #endif
88              
89             #if defined(HAS_POLL)
90             # include
91              
92             /*
93             Many operating systems claim to support poll yet they
94             actually emulate it with select. c/unix.c supports
95             either poll or select but it doesn't know which one to
96             use. Here we try to detect if we have a native poll
97             implementation. If we do, we use it. Otherwise,
98             select is assumed.
99             */
100              
101             # ifndef POLLOUT
102             # undef HAS_POLL
103             # endif
104             # ifndef POLLWRNORM
105             # undef HAS_POLL
106             # endif
107             # ifndef POLLWRBAND
108             # undef HAS_POLL
109             # endif
110             #endif
111              
112             /* Is time() portable everywhere? Hope so! XXX */
113              
114 0           static NV fallback_NVtime()
115 0           { return time(0); }
116              
117             #include "Event.h"
118              
119             /* The following is for very simplistic memory leak detection. */
120              
121             #define MAX_MEMORYCOUNT 20
122             static int MemoryCount[MAX_MEMORYCOUNT];
123 0           static void dbg_count_memory(int id, int cnt) {
124             assert(id >= 0 && id < MAX_MEMORYCOUNT);
125 0           MemoryCount[id] += cnt;
126 0           }
127              
128             #if EVENT_MEMORY_DEBUG
129             # define EvNew(id, ptr, size, type) dbg_count_memory(id,1); New(0,ptr,size,type)
130             # define EvFree(id, ptr) STMT_START { dbg_count_memory(id,-1); safefree(ptr); } STMT_END
131             #else
132             # define EvNew(x, ptr, size, type) New(0,ptr,size,type)
133             # define EvFree(id, ptr) safefree(ptr)
134             #endif
135              
136             static int LoopLevel, ExitLevel;
137             static int ActiveWatchers=0; /* includes WaACTIVE + queued events */
138             static int WarnCounter=16; /*XXX nuke */
139             static SV *DebugLevel;
140             static SV *Eval;
141             static pe_event_stats_vtbl Estat;
142              
143             /* IntervalEpsilon should be equal to the clock's sleep resolution
144             (poll or select) times two. It probably needs to be bigger if you turn
145             on lots of debugging? Can determine this dynamically? XXX */
146             static NV IntervalEpsilon = 0.0002;
147             static int TimeoutTooEarly=0;
148              
149             static struct EventAPI api;
150             #define NVtime() (*api.NVtime)()
151              
152             static int pe_sys_fileno(SV *sv, char *context);
153              
154             static void queueEvent(pe_event *ev);
155             static void dequeEvent(pe_event *ev);
156              
157             static void pe_watcher_cancel(pe_watcher *ev);
158             static void pe_watcher_suspend(pe_watcher *ev);
159             static void pe_watcher_resume(pe_watcher *ev);
160             static void pe_watcher_now(pe_watcher *ev);
161             static void pe_watcher_start(pe_watcher *ev, int repeat);
162             static void pe_watcher_stop(pe_watcher *ev, int cancel_events);
163             static char*pe_watcher_on(pe_watcher *wa, int repeat);
164             static void pe_watcher_off(pe_watcher *wa);
165              
166             /* The newHVhv in perl seems to mysteriously break in some cases. Here
167             is a simple and safe (but maybe slow) implementation. */
168              
169             #ifdef newHVhv
170             # undef newHVhv
171             #endif
172             #define newHVhv event_newHVhv
173              
174 0           static HV *event_newHVhv(HV *ohv) {
175 0           register HV *hv = newHV();
176             register HE *entry;
177 0           hv_iterinit(ohv); /* NOTE: this resets the iterator */
178 0 0         while (entry = hv_iternext(ohv)) {
179 0           hv_store(hv, HeKEY(entry), HeKLEN(entry),
180             SvREFCNT_inc(HeVAL(entry)), HeHASH(entry));
181             }
182 0           return hv;
183             }
184              
185 0           static void pe_watcher_STORE_FALLBACK(pe_watcher *wa, SV *svkey, SV *nval)
186             {
187 0 0         if (!wa->FALLBACK)
188 0           wa->FALLBACK = newHV();
189 0           hv_store_ent(wa->FALLBACK, svkey, SvREFCNT_inc(nval), 0);
190 0           }
191              
192             /***************** STATS */
193             static int StatsInstalled=0;
194 0           static void pe_install_stats(pe_event_stats_vtbl *esvtbl) {
195 0           ++StatsInstalled;
196 0           Copy(esvtbl, &Estat, 1, pe_event_stats_vtbl);
197 0           Estat.on=0;
198 0           }
199 0           static void pe_collect_stats(int yes) {
200 0 0         if (!StatsInstalled)
201 0           croak("collect_stats: no event statistics are available");
202 0           Estat.on = yes;
203 0           }
204              
205             #ifdef HAS_GETTIMEOFDAY
206 0           NV null_loops_per_second(int sec)
207             {
208             /*
209             This should be more realistic. It is used to normalize
210             the benchmark against some theoretical perfect event loop.
211             */
212             struct timeval start_tm, done_tm;
213             NV elapse;
214 0           unsigned count=0;
215             int fds[2];
216 0 0         if (pipe(fds) != 0) croak("pipe");
217 0           gettimeofday(&start_tm, 0);
218             do {
219             #ifdef HAS_POLL
220             struct pollfd map[2];
221 0           Zero(map, 2, struct pollfd);
222 0           map[0].fd = fds[0];
223 0           map[0].events = POLLIN | POLLOUT;
224 0           map[0].revents = 0;
225 0           map[1].fd = fds[1];
226 0           map[1].events = POLLIN | POLLOUT;
227 0           map[1].revents = 0;
228 0           poll(map, 2, 0);
229             #elif defined(HAS_SELECT)
230             struct timeval null;
231             fd_set rfds, wfds, efds;
232             FD_ZERO(&rfds);
233             FD_ZERO(&wfds);
234             FD_ZERO(&efds);
235             FD_SET(fds[0], &rfds);
236             FD_SET(fds[0], &wfds);
237             FD_SET(fds[1], &rfds);
238             FD_SET(fds[1], &wfds);
239             null.tv_sec = 0;
240             null.tv_usec = 0;
241             select(3,&rfds,&wfds,&efds,&null);
242             #else
243             # error
244             #endif
245 0           ++count;
246 0           gettimeofday(&done_tm, 0);
247 0           elapse = (done_tm.tv_sec - start_tm.tv_sec +
248 0           (done_tm.tv_usec - start_tm.tv_usec) / 1000000);
249 0 0         } while(elapse < sec);
250 0           close(fds[0]);
251 0           close(fds[1]);
252 0           return count/sec;
253             }
254             #else /* !HAS_GETTIMEOFDAY */
255             NV null_loops_per_second(int sec)
256             { croak("sorry, gettimeofday is not available"); }
257             #endif
258              
259              
260             #include "typemap.c"
261             #include "timeable.c"
262             #include "hook.c"
263             #include "ev.c"
264             #include "watcher.c"
265             #include "idle.c"
266             #include "timer.c"
267             #include "io.c"
268             #include "unix.c"
269             #include "var.c"
270             #include "signal.c"
271             #include "tied.c"
272             #include "group.c"
273             #include "generic.c"
274             #include "queue.c"
275              
276             MODULE = Event PACKAGE = Event
277              
278             PROTOTYPES: DISABLE
279              
280             BOOT:
281 25           LoopLevel = ExitLevel = 0;
282 25           DebugLevel = SvREFCNT_inc(perl_get_sv("Event::DebugLevel", 1));
283 25           Eval = SvREFCNT_inc(perl_get_sv("Event::Eval", 1));
284 25           Estat.on=0;
285 25           boot_timeable();
286 25           boot_hook();
287 25           boot_pe_event();
288 25           boot_pe_watcher();
289 25           boot_idle();
290 25           boot_timer();
291 25           boot_io();
292 25           boot_devpoll();
293 25           boot_var();
294 25           boot_tied();
295 25           boot_signal();
296 25           boot_group();
297 25           boot_generic();
298 25           boot_queue();
299             {
300             SV *apisv;
301 25           api.Ver = EventAPI_VERSION;
302 25           api.start = pe_watcher_start;
303 25           api.queue = queueEvent;
304 25           api.now = pe_watcher_now;
305 25           api.suspend = pe_watcher_suspend;
306 25           api.resume = pe_watcher_resume;
307 25           api.stop = pe_watcher_stop;
308 25           api.cancel = pe_watcher_cancel;
309 25           api.tstart = pe_timeable_start;
310 25           api.tstop = pe_timeable_stop;
311 25           api.NVtime = fallback_NVtime;
312 25           api.new_idle = (pe_idle* (*)(HV*,SV*)) pe_idle_allocate;
313 25           api.new_timer = (pe_timer* (*)(HV*,SV*)) pe_timer_allocate;
314 25           api.new_io = (pe_io* (*)(HV*,SV*)) pe_io_allocate;
315 25           api.new_var = (pe_var* (*)(HV*,SV*)) pe_var_allocate;
316 25           api.new_signal = (pe_signal*(*)(HV*,SV*)) pe_signal_allocate;
317 25           api.add_hook = capi_add_hook;
318 25           api.cancel_hook = pe_cancel_hook;
319 25           api.install_stats = pe_install_stats;
320 25           api.collect_stats = pe_collect_stats;
321 25           api.AllWatchers = &AllWatchers;
322 25           api.watcher_2sv = watcher_2sv;
323 25           api.sv_2watcher = sv_2watcher;
324 25           api.event_2sv = event_2sv;
325 25           api.sv_2event = sv_2event;
326 25           api.unloop = pe_unloop;
327 25           api.unloop_all = pe_unloop_all;
328 25           api.sv_2interval = sv_2interval;
329 25           api.events_mask_2sv = events_mask_2sv;
330 25           api.sv_2events_mask = sv_2events_mask;
331              
332 25           apisv = perl_get_sv("Event::API", 1);
333 25           sv_setiv(apisv, (IV)&api);
334 25           SvREADONLY_on(apisv);
335             }
336              
337             void
338             _add_hook(type, code)
339             char *type
340             SV *code
341             CODE:
342 4           pe_add_hook(type, 1, code, 0);
343             /* would be nice to return new pe_qcallback* XXX */
344              
345             int
346             _timeout_too_early()
347             CODE:
348 0           RETVAL = TimeoutTooEarly;
349 0           TimeoutTooEarly=0;
350             OUTPUT:
351             RETVAL
352              
353             void
354             _memory_counters()
355             PPCODE:
356             {
357             #ifdef EVENT_MEMORY_DEBUG
358             int xx;
359             for (xx=0; xx < MAX_MEMORYCOUNT; xx++)
360             XPUSHs(sv_2mortal(newSViv(MemoryCount[xx])));
361             #endif
362             }
363              
364             void
365             _incr_looplevel()
366             PPCODE:
367 117           ++LoopLevel;
368 117           ++ExitLevel;
369              
370             void
371             _decr_looplevel()
372             PPCODE:
373 117           --LoopLevel;
374              
375             void
376             unloop(...)
377             CODE:
378 13 100         pe_unloop(items? ST(0) : &PL_sv_undef);
379              
380             void
381             unloop_all(...)
382             CODE:
383 1 50         pe_unloop_all(items? ST(0) : &PL_sv_undef);
384              
385             bool
386             cache_time_api()
387             CODE:
388 24           SV **svp = hv_fetch(PL_modglobal, "Time::NVtime", 12, 0);
389 24 50         if (!svp || !*svp || !SvIOK(*svp))
    50          
    50          
390 0           XSRETURN_NO;
391 24 50         api.NVtime = INT2PTR(NV(*)(), SvIV(*svp));
392 24           XSRETURN_YES;
393              
394             NV
395             time()
396             PROTOTYPE:
397             CODE:
398 42           RETVAL = NVtime();
399             OUTPUT:
400             RETVAL
401              
402             void
403             sleep(tm)
404             NV tm;
405             PROTOTYPE: $
406             CODE:
407 1           pe_sys_sleep(tm);
408              
409             NV
410             null_loops_per_second(sec)
411             int sec
412              
413             void
414             all_watchers()
415             PROTOTYPE:
416             PPCODE:
417             pe_watcher *ev;
418 30 50         if (!AllWatchers.next)
419 0           return;
420 30           ev = (pe_watcher*) AllWatchers.next->self;
421 3211 100         while (ev) {
422 3181 100         XPUSHs(watcher_2sv(ev));
423 3181           ev = (pe_watcher*) ev->all.next->self;
424             }
425              
426             void
427             all_idle()
428             PROTOTYPE:
429             PPCODE:
430             pe_watcher *ev;
431 1 50         if (!Idle.prev)
432 0           return;
433 1           ev = (pe_watcher*) Idle.prev->self;
434 1 50         while (ev) {
435 0 0         XPUSHs(watcher_2sv(ev));
436 0           ev = (pe_watcher*) ((pe_idle*)ev)->iring.prev->self;
437             }
438              
439             void
440             all_running()
441             PROTOTYPE:
442             PPCODE:
443             int fx;
444 13 100         for (fx = CurCBFrame; fx >= 0; fx--) {
445 12           pe_watcher *ev = (CBFrame + fx)->ev->up; /* XXX */
446 12 50         XPUSHs(watcher_2sv(ev));
447 12 50         if (GIMME_V != G_ARRAY)
    100          
448 1           break;
449             }
450              
451             void
452             queue(...)
453             PROTOTYPE: $;$
454             PREINIT:
455             pe_watcher *wa;
456             pe_event *ev;
457             PPCODE:
458 0           wa = (pe_watcher*) sv_2watcher(ST(0));
459 0 0         if (items == 1) {
460 0           ev = (*wa->vtbl->new_event)(wa);
461 0           ++ev->hits;
462             }
463 0 0         else if (items == 2) {
464 0 0         if (SvNIOK(ST(1))) {
465 0           ev = (*wa->vtbl->new_event)(wa);
466 0 0         ev->hits += SvIV(ST(1));
467             }
468             else {
469 0           ev = (pe_event*) sv_2event(ST(1));
470 0 0         if (ev->up != wa)
471 0           croak("queue: event doesn't match watcher");
472             }
473             }
474 0           queueEvent(ev);
475              
476             int
477             one_event(...)
478             PROTOTYPE: ;$
479             CODE:
480 21           NV maxtm = 60;
481 21 50         if (items == 1) maxtm = SvNV(ST(0));
    0          
482 21           RETVAL = safe_one_event(maxtm);
483             OUTPUT:
484             RETVAL
485              
486             void
487             _loop()
488             CODE:
489 121           pe_check_recovery();
490 121           pe_reentry();
491 121 100         if (!ActiveWatchers)
492 2           warn("Event: loop without active watchers");
493 106252 100         while (ExitLevel >= LoopLevel && ActiveWatchers) {
    100          
494 106135           ENTER;
495 106135           SAVETMPS;
496 106135           one_event(60);
497 106131 100         FREETMPS;
498 106131           LEAVE;
499             }
500 117           LEAVE; /* reentry */
501              
502             void
503             queue_pending()
504             CODE:
505 3           pe_queue_pending();
506              
507             int
508             _empty_queue(prio)
509             int prio
510             CODE:
511 5           pe_check_recovery();
512 5           pe_reentry();
513 6 100         while (pe_empty_queue(prio));
514 3           LEAVE; /* reentry */
515              
516             void
517             queue_time(prio)
518             int prio
519             PPCODE:
520 0           NV max=0;
521             int xx;
522 0 0         if (prio < 0 || prio >= PE_QUEUES)
    0          
523 0           croak("queue_time(%d) out of domain [0..%d]",
524             prio, PE_QUEUES-1);
525 0 0         for (xx=0; xx <= prio; xx++)
526 0 0         if (max < QueueTime[xx]) max = QueueTime[xx];
527 0 0         XPUSHs(max? sv_2mortal(newSVnv(max)) : &PL_sv_undef);
    0          
528              
529              
530             MODULE = Event PACKAGE = Event::Event::Io
531              
532             void
533             pe_event::got()
534             PPCODE:
535 94103 50         XPUSHs(sv_2mortal(events_mask_2sv(((pe_ioevent*)THIS)->got)));
536              
537             MODULE = Event PACKAGE = Event::Event::Dataful
538              
539             void
540             pe_event::data()
541             PPCODE:
542 3 50         XPUSHs(((pe_datafulevent*)THIS)->data);
543              
544             MODULE = Event PACKAGE = Event::Event
545              
546             void
547             DESTROY(ref)
548             SV *ref;
549             CODE:
550             {
551 94968           pe_event *THIS = (pe_event*) sv_2event(ref);
552             if (WaDEBUGx(THIS) >= 3) {
553             STRLEN n_a;
554             warn("Event=0x%x '%s' DESTROY SV=0x%x",
555             THIS, SvPV(THIS->up->desc, n_a),
556             THIS->mysv? SvRV(THIS->mysv) : 0);
557             }
558 94968           (*THIS->vtbl->dtor)(THIS);
559             }
560              
561             void
562             pe_event::mom()
563             PPCODE:
564 0 0         if (--WarnCounter >= 0) warn("'mom' renamed to 'w'");
565 0 0         XPUSHs(watcher_2sv(THIS->up));
566              
567             void
568             pe_event::w()
569             PPCODE:
570 94750 50         XPUSHs(watcher_2sv(THIS->up));
571              
572             void
573             pe_event::hits()
574             PPCODE:
575 3 50         XPUSHs(sv_2mortal(newSViv(THIS->hits)));
576              
577             void
578             pe_event::prio()
579             PPCODE:
580 4 50         XPUSHs(sv_2mortal(newSViv(THIS->prio)));
581              
582             MODULE = Event PACKAGE = Event::Watcher
583              
584             void
585             DESTROY(ref)
586             SV *ref;
587             CODE:
588             {
589 3818           pe_watcher *THIS = (pe_watcher*) sv_2watcher(ref);
590             assert(THIS);
591 3818 50         if (THIS->mysv) {
592 3818           THIS->mysv=0;
593 3818 50         if (WaCANDESTROY(THIS)) /*mysv*/
    100          
    50          
594 3193           (*THIS->vtbl->dtor)(THIS);
595             }
596             }
597              
598             void
599             pe_watcher::pending()
600             PPCODE:
601             {
602 4 50         if (GIMME_V == G_ARRAY) {
    100          
603 2           pe_event *ev = (pe_event *) THIS->events.prev->self;
604 7 100         while (ev) {
605 5 50         XPUSHs(event_2sv(ev));
606 5           ev = (pe_event*) ev->peer.prev->self;
607             }
608             } else {
609 2 50         XPUSHs(THIS->events.next->self? &PL_sv_yes : &PL_sv_no);
    100          
610             }
611             }
612              
613             void
614             pe_watcher::again()
615             CODE:
616 6           pe_watcher_start(THIS, 1);
617              
618             void
619             pe_watcher::start()
620             CODE:
621 3807           pe_watcher_start(THIS, 0);
622              
623             void
624             pe_watcher::suspend(...)
625             CODE:
626 0 0         if (items == 2) {
627 0 0         if (sv_true(ST(1)))
628 0           pe_watcher_suspend(THIS);
629             else
630 0           pe_watcher_resume(THIS);
631             } else {
632 0           warn("Ambiguous use of suspend"); /*XXX*/
633 0           pe_watcher_suspend(THIS);
634 0           XSRETURN_YES;
635             }
636              
637             void
638             pe_watcher::resume()
639             CODE:
640 0           warn("Please use $w->suspend(0) instead of resume"); /* DEPRECATED */
641 0           pe_watcher_resume(THIS);
642              
643             void
644             pe_watcher::stop()
645             CODE:
646 6           pe_watcher_stop(THIS, 1);
647              
648             void
649             pe_watcher::cancel()
650             CODE:
651 3820           pe_watcher_cancel(THIS);
652              
653             void
654             pe_watcher::now()
655             CODE:
656 16           pe_watcher_now(THIS);
657              
658             void
659             pe_watcher::use_keys(...)
660             PREINIT:
661             PPCODE:
662 0           warn("use_keys is deprecated");
663              
664             void
665             pe_watcher::is_running(...)
666             PPCODE:
667 1 50         XPUSHs(sv_2mortal(newSViv(THIS->running)));
668              
669             void
670             pe_watcher::is_active(...)
671             PPCODE:
672 0           PUTBACK;
673 0 0         XPUSHs(boolSV(WaACTIVE(THIS)));
    0          
674              
675             void
676             pe_watcher::is_suspended(...)
677             PPCODE:
678 0           PUTBACK;
679 0 0         XPUSHs(boolSV(WaSUSPEND(THIS)));
    0          
680              
681             void
682             pe_watcher::is_cancelled(...)
683             PPCODE:
684 2           PUTBACK;
685 2 50         XPUSHs(boolSV(WaCANCELLED(THIS)));
    100          
686              
687             void
688             pe_watcher::cb(...)
689             PPCODE:
690 3812           PUTBACK;
691 3812 100         _watcher_callback(THIS, items == 2? sv_mortalcopy(ST(1)) : 0);
692 3811           SPAGAIN;
693              
694             void
695             pe_watcher::cbtime(...)
696             PPCODE:
697 2           PUTBACK;
698 2 50         _watcher_cbtime(THIS, items == 2? sv_mortalcopy(ST(1)) : 0);
699 2           SPAGAIN;
700              
701             void
702             pe_watcher::desc(...)
703             PPCODE:
704 3832           PUTBACK;
705 3832 100         _watcher_desc(THIS, items == 2? sv_mortalcopy(ST(1)) : 0);
706 3832           SPAGAIN;
707              
708             void
709             pe_watcher::debug(...)
710             PPCODE:
711 1           PUTBACK;
712 1 50         _watcher_debug(THIS, items == 2? sv_mortalcopy(ST(1)) : 0);
713 1           SPAGAIN;
714              
715             void
716             pe_watcher::prio(...)
717             PPCODE:
718 7563           PUTBACK;
719 7563 100         _watcher_priority(THIS, items == 2? sv_mortalcopy(ST(1)) : 0);
720 7563           SPAGAIN;
721              
722             void
723             pe_watcher::reentrant(...)
724             PPCODE:
725 2           PUTBACK;
726 2 100         _watcher_reentrant(THIS, items == 2? sv_mortalcopy(ST(1)) : 0);
727 2           SPAGAIN;
728              
729             void
730             pe_watcher::repeat(...)
731             PPCODE:
732 3737           PUTBACK;
733 3737 100         _watcher_repeat(THIS, items == 2? sv_mortalcopy(ST(1)) : 0);
734 3737           SPAGAIN;
735              
736             void
737             pe_watcher::max_cb_tm(...)
738             PPCODE:
739 1           PUTBACK;
740 1 50         _watcher_max_cb_tm(THIS, items == 2? sv_mortalcopy(ST(1)) : 0);
741 1           SPAGAIN;
742              
743             MODULE = Event PACKAGE = Event::Watcher::Tied
744              
745             void
746             allocate(clname, temple)
747             SV *clname
748             SV *temple
749             PPCODE:
750 0 0         if (!SvROK(temple)) croak("Bad template");
751 0 0         XPUSHs(watcher_2sv(pe_tied_allocate(gv_stashsv(clname, 1),
752             SvRV(temple))));
753              
754             void
755             pe_watcher::hard(...)
756             PPCODE:
757 0           PUTBACK;
758 0 0         _timeable_hard(THIS, items == 2? sv_mortalcopy(ST(1)) : 0);
759 0           SPAGAIN;
760              
761             void
762             pe_watcher::at(...)
763             PPCODE:
764 0           PUTBACK;
765 0 0         _tied_at(THIS, items == 2? sv_mortalcopy(ST(1)) : 0);
766 0           SPAGAIN;
767              
768             void
769             pe_watcher::flags(...)
770             PPCODE:
771 0           PUTBACK;
772 0 0         _tied_flags(THIS, items == 2? sv_mortalcopy(ST(1)) : 0);
773 0           SPAGAIN;
774              
775             MODULE = Event PACKAGE = Event::idle
776              
777             void
778             allocate(clname, temple)
779             SV *clname;
780             SV *temple;
781             PPCODE:
782 13 50         if (!SvROK(temple)) croak("Bad template");
783 13 50         XPUSHs(watcher_2sv(pe_idle_allocate(gv_stashsv(clname, 1),
784             SvRV(temple))));
785              
786             void
787             pe_watcher::hard(...)
788             PPCODE:
789 1           PUTBACK;
790 1 50         _timeable_hard(THIS, items == 2? sv_mortalcopy(ST(1)) : 0);
791 1           SPAGAIN;
792              
793             void
794             pe_watcher::max(...)
795             PPCODE:
796 1           PUTBACK;
797 1 50         _idle_max_interval(THIS, items == 2? sv_mortalcopy(ST(1)) : 0);
798 1           SPAGAIN;
799              
800             void
801             pe_watcher::min(...)
802             PPCODE:
803 1           PUTBACK;
804 1 50         _idle_min_interval(THIS, items == 2? sv_mortalcopy(ST(1)) : 0);
805 1           SPAGAIN;
806              
807             MODULE = Event PACKAGE = Event::timer
808              
809             void
810             allocate(clname, temple)
811             SV *clname;
812             SV *temple;
813             PPCODE:
814 46 50         XPUSHs(watcher_2sv(pe_timer_allocate(gv_stashsv(clname, 1),
815             SvRV(temple))));
816              
817             void
818             pe_watcher::at(...)
819             PPCODE:
820 47           PUTBACK;
821 47 100         _timer_at(THIS, items == 2? sv_mortalcopy(ST(1)) : 0);
822 47           SPAGAIN;
823              
824             void
825             pe_watcher::hard(...)
826             PPCODE:
827 0           PUTBACK;
828 0 0         _timeable_hard(THIS, items == 2? sv_mortalcopy(ST(1)) : 0);
829 0           SPAGAIN;
830              
831             void
832             pe_watcher::interval(...)
833             PPCODE:
834 42           PUTBACK;
835 42 100         _timer_interval(THIS, items == 2? sv_mortalcopy(ST(1)) : 0);
836 42           SPAGAIN;
837              
838             MODULE = Event PACKAGE = Event::io
839              
840             void
841             allocate(clname, temple)
842             SV *clname;
843             SV *temple;
844             PPCODE:
845 3743 50         if (!SvROK(temple)) croak("Bad template");
846 3743 50         XPUSHs(watcher_2sv(pe_io_allocate(gv_stashsv(clname, 1),
847             SvRV(temple))));
848              
849             void
850             pe_watcher::poll(...)
851             PPCODE:
852 6           PUTBACK;
853 6 50         _io_poll(THIS, items == 2? sv_mortalcopy(ST(1)) : 0);
854 6           SPAGAIN;
855              
856             void
857             pe_watcher::fd(...)
858             PPCODE:
859 94104           PUTBACK;
860 94104 100         _io_handle(THIS, items == 2? sv_mortalcopy(ST(1)) : 0);
861 94104           SPAGAIN;
862              
863             void
864             pe_watcher::timeout(...)
865             PPCODE:
866 3734           PUTBACK;
867 3734 100         _io_timeout(THIS, items == 2? sv_mortalcopy(ST(1)) : 0);
868 3734           SPAGAIN;
869              
870             void
871             pe_watcher::timeout_cb(...)
872             PPCODE:
873 6           PUTBACK;
874 6 50         _io_timeout_cb(THIS, items == 2? sv_mortalcopy(ST(1)) : 0);
875 6           SPAGAIN;
876              
877             MODULE = Event PACKAGE = Event::var
878              
879             void
880             allocate(clname, temple)
881             SV *clname;
882             SV *temple;
883             PPCODE:
884 10 50         XPUSHs(watcher_2sv(pe_var_allocate(gv_stashsv(clname, 1),
885             SvRV(temple))));
886              
887             void
888             pe_watcher::var(...)
889             PPCODE:
890 8           PUTBACK;
891 8 100         _var_variable(THIS, items == 2? ST(1) : 0); /* don't mortalcopy!! */
892 8           SPAGAIN;
893              
894             void
895             pe_watcher::poll(...)
896             PPCODE:
897 2           PUTBACK;
898 2 50         _var_events(THIS, items == 2? sv_mortalcopy(ST(1)) : 0);
899 2           SPAGAIN;
900              
901             MODULE = Event PACKAGE = Event::signal
902              
903             void
904             allocate(clname, temple)
905             SV *clname;
906             SV *temple;
907             PPCODE:
908 4 50         XPUSHs(watcher_2sv(pe_signal_allocate(gv_stashsv(clname, 1),
909             SvRV(temple))));
910              
911             void
912             pe_watcher::signal(...)
913             PPCODE:
914 2           PUTBACK;
915 2 100         _signal_signal(THIS, items == 2? sv_mortalcopy(ST(1)) : 0);
916 2           SPAGAIN;
917              
918             MODULE = Event PACKAGE = Event::group
919              
920             void
921             allocate(clname, temple)
922             SV *clname;
923             SV *temple;
924             PPCODE:
925 1 50         XPUSHs(watcher_2sv(pe_group_allocate(gv_stashsv(clname, 1),
926             SvRV(temple))));
927              
928             void
929             pe_watcher::timeout(...)
930             PPCODE:
931 1           PUTBACK;
932 1 50         _group_timeout(THIS, items == 2? sv_mortalcopy(ST(1)) : 0);
933 1           SPAGAIN;
934              
935             void
936             pe_watcher::add(...)
937             PPCODE:
938 13           PUTBACK;
939 13 50         _group_add(THIS, items == 2? sv_mortalcopy(ST(1)) : 0);
940 10           SPAGAIN;
941              
942             void
943             pe_watcher::del(...)
944             PPCODE:
945 0           PUTBACK;
946 0 0         _group_del(THIS, items == 2? sv_mortalcopy(ST(1)) : 0);
947 0           SPAGAIN;
948              
949             MODULE = Event PACKAGE = Event::generic
950              
951             void
952             allocate(clname, temple)
953             SV *clname;
954             SV *temple;
955             PPCODE:
956 2 50         XPUSHs(watcher_2sv(pe_generic_allocate(gv_stashsv(clname, 1),
957             SvRV(temple))));
958              
959             void
960             pe_watcher::source(...)
961             PPCODE:
962 6           PUTBACK;
963 6 50         _generic_source(THIS, items == 2? sv_mortalcopy(ST(1)) : 0);
964 3           SPAGAIN;
965              
966             MODULE = Event PACKAGE = Event::generic::Source
967              
968             void
969             allocate(clname, temple)
970             SV *clname;
971             SV *temple;
972             PPCODE:
973 1 50         if (!SvROK(temple)) croak("Bad template");
974 1 50         XPUSHs(genericsrc_2sv(pe_genericsrc_allocate(gv_stashsv(clname, 1),
975             SvRV(temple))));
976              
977             void
978             DESTROY(ref)
979             SV *ref;
980             CODE:
981             {
982 1           pe_genericsrc_dtor(sv_2genericsrc(ref));
983             }
984              
985             void
986             pe_genericsrc::event(...)
987             PPCODE:
988 2 50         pe_genericsrc_event(THIS,
989 2           items >= 2 ? sv_mortalcopy(ST(1)) : &PL_sv_undef);