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
|
25
|
|
|
|
|
|
static void boot_timer() { |
85
|
25
|
|
|
|
|
|
pe_watcher_vtbl *vt = &pe_timer_vtbl; |
86
|
25
|
|
|
|
|
|
memcpy(vt, &pe_watcher_base_vtbl, sizeof(pe_watcher_base_vtbl)); |
87
|
25
|
|
|
|
|
|
vt->dtor = pe_timer_dtor; |
88
|
25
|
|
|
|
|
|
vt->start = pe_timer_start; |
89
|
25
|
|
|
|
|
|
vt->stop = pe_timer_stop; |
90
|
25
|
|
|
|
|
|
vt->alarm = pe_timer_alarm; |
91
|
25
|
|
|
|
|
|
pe_register_vtbl(vt, gv_stashpv("Event::timer",1), &event_vtbl); |
92
|
25
|
|
|
|
|
|
} |