File Coverage

c/timer.c
Criterion Covered Total %
statement 62 64 96.8
branch 19 24 79.1
condition n/a
subroutine n/a
pod n/a
total 81 88 92.0


line stmt bran cond sub pod time code
1             static struct pe_watcher_vtbl pe_timer_vtbl;
2              
3 46           static pe_watcher *pe_timer_allocate(HV *stash, SV *temple) {
4             pe_timer *ev;
5 46           EvNew(7, ev, 1, pe_timer);
6             assert(ev);
7 46           ev->base.vtbl = &pe_timer_vtbl;
8 46           PE_RING_INIT(&ev->tm.ring, ev);
9 46           ev->tm.at = 0;
10 46           ev->interval = &PL_sv_undef;
11 46           pe_watcher_init(&ev->base, stash, temple);
12 45           return (pe_watcher*) ev;
13             }
14              
15 45           static void pe_timer_dtor(pe_watcher *ev) {
16 45           pe_timer *tm = (pe_timer*) ev;
17 45           SvREFCNT_dec(tm->interval);
18 45           pe_watcher_dtor(ev);
19 45           EvFree(7, ev);
20 45           }
21              
22 86           static char *pe_timer_start(pe_watcher *ev, int repeat) {
23             STRLEN n_a;
24 86           pe_timer *tm = (pe_timer*) ev;
25 86 50         if (!ev->callback)
26 0           return "without callback";
27 86 100         if (repeat) {
28             /* We just finished the callback and need to re-insert at
29             the appropriate time increment. */
30             NV interval;
31              
32 42 50         if (!sv_2interval("timer", tm->interval, &interval))
33 0           return "repeating timer has no interval";
34              
35 42 50         tm->tm.at = interval + (WaHARD(ev)? tm->tm.at : NVtime());
36             }
37 86 100         if (!tm->tm.at)
38 1           return "timer unset";
39              
40 85           pe_timeable_start(&tm->tm);
41 85           return 0;
42             }
43              
44 85           static void pe_timer_stop(pe_watcher *ev)
45 85           { pe_timeable_stop(&((pe_timer*)ev)->tm); }
46              
47 54           static void pe_timer_alarm(pe_watcher *wa, pe_timeable *tm) {
48 54           pe_event *ev = (*wa->vtbl->new_event)(wa);
49 54           ++ev->hits;
50 54           queueEvent(ev);
51 54           }
52              
53 47           WKEYMETH(_timer_at) {
54 47           pe_timer *tp = (pe_timer*)ev;
55 47 100         if (nval) {
56 44           int active = WaPOLLING(ev);
57 44 100         if (active) pe_watcher_off(ev);
58 44 100         tp->tm.at = SvNV(nval);
59 44 100         if (active) pe_watcher_on(ev, 0);
60             }
61             {
62 47           dSP;
63 47 50         XPUSHs(sv_2mortal(newSVnv(tp->tm.at)));
64 47           PUTBACK;
65             }
66 47           }
67              
68 42           WKEYMETH(_timer_interval) {
69 42           pe_timer *tp = (pe_timer*)ev;
70 42 100         if (nval) {
71 41           SV *old = tp->interval;
72 41           tp->interval = SvREFCNT_inc(nval);
73 41           SvREFCNT_dec(old);
74 41           VERIFYINTERVAL("timer", tp->interval);
75             /* recalc expiration XXX */
76             }
77             {
78 42           dSP;
79 42 50         XPUSHs(tp->interval);
80 42           PUTBACK;
81             }
82 42           }
83              
84 24           static void boot_timer() {
85 24           pe_watcher_vtbl *vt = &pe_timer_vtbl;
86 24           memcpy(vt, &pe_watcher_base_vtbl, sizeof(pe_watcher_base_vtbl));
87 24           vt->dtor = pe_timer_dtor;
88 24           vt->start = pe_timer_start;
89 24           vt->stop = pe_timer_stop;
90 24           vt->alarm = pe_timer_alarm;
91 24           pe_register_vtbl(vt, gv_stashpv("Event::timer",1), &event_vtbl);
92 24           }