File: tied.c

package info (click to toggle)
libevent-perl 1.15-1
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 792 kB
  • sloc: ansic: 3,034; perl: 1,128; makefile: 2
file content (104 lines) | stat: -rw-r--r-- 2,563 bytes parent folder | download | duplicates (9)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
static struct pe_watcher_vtbl pe_tied_vtbl;

static pe_watcher *pe_tied_allocate(HV *stash, SV *temple) {
    pe_tied *ev;
    EvNew(6, ev, 1, pe_tied);
    ev->base.vtbl = &pe_tied_vtbl;
    if (!stash) croak("tied_allocate(0)");
    pe_watcher_init(&ev->base, stash, temple);
    PE_RING_INIT(&ev->tm.ring, ev);
    return (pe_watcher*) ev;
}

static void pe_tied_dtor(pe_watcher *ev) {
    pe_watcher_dtor(ev);
    EvFree(6, ev);
}

static char *pe_tied_start(pe_watcher *ev, int repeat) {
    HV *stash = SvSTASH(SvRV(ev->mysv));
    GV *gv;
    dSP;
    assert(stash);
    PUSHMARK(SP);
    XPUSHs(watcher_2sv(ev));
    XPUSHs(boolSV(repeat));
    PUTBACK;
    gv = gv_fetchmethod(stash, "_start");
    if (!gv)
	croak("Cannot find %s->_start()", HvNAME(stash));
    perl_call_sv((SV*)GvCV(gv), G_DISCARD);
    /* allow return of error! XXX */
    return 0;
}

static void pe_tied_stop(pe_watcher *ev) {
    HV *stash = SvSTASH(SvRV(ev->mysv));
    GV *gv = gv_fetchmethod(stash, "_stop");
    pe_timeable_stop(&((pe_tied*)ev)->tm);
    if (gv) {
	dSP;
	PUSHMARK(SP);
	XPUSHs(watcher_2sv(ev));
	PUTBACK;
	perl_call_sv((SV*)GvCV(gv), G_DISCARD);
    }
}

static void pe_tied_alarm(pe_watcher *ev, pe_timeable *_ign) {
    HV *stash = SvSTASH(SvRV(ev->mysv));
    GV *gv;
    dSP;
    PUSHMARK(SP);
    XPUSHs(watcher_2sv(ev));
    PUTBACK;
    gv = gv_fetchmethod(stash, "_alarm");
    if (!gv)
	croak("Cannot find %s->_alarm()", HvNAME(stash));
    perl_call_sv((SV*)GvCV(gv), G_DISCARD);
}

WKEYMETH(_tied_at) {
    pe_tied *tp = (pe_tied*) ev;
    if (nval) {
	pe_timeable_stop(&tp->tm);
	if (SvOK(nval)) {
	    tp->tm.at = SvNV(nval);
	    pe_timeable_start(&tp->tm);
	}
    }
    {
	dSP;
	XPUSHs(sv_2mortal(newSVnv(tp->tm.at)));
	PUTBACK;
    }
}

WKEYMETH(_tied_flags) {
    if (nval) {
	IV nflags = SvIV(nval);
	IV flip = nflags ^ ev->flags;
	IV other = flip & ~(PE_INVOKE1);
	if (flip & PE_INVOKE1) {
	    if (nflags & PE_INVOKE1) WaINVOKE1_on(ev); else WaINVOKE1_off(ev);
	}
	if (other)
	    warn("Other flags (0x%x) cannot be changed", other);
    }
    {
	dSP;
	XPUSHs(sv_2mortal(newSViv(ev->flags & PE_VISIBLE_FLAGS)));
	PUTBACK;
    }
}

static void boot_tied() {
    pe_watcher_vtbl *vt = &pe_tied_vtbl;
    memcpy(vt, &pe_watcher_base_vtbl, sizeof(pe_watcher_base_vtbl));
    vt->did_require = 1; /* otherwise tries to autoload Event::Event! */
    vt->dtor = pe_tied_dtor;
    vt->start = pe_tied_start;
    vt->stop = pe_tied_stop;
    vt->alarm = pe_tied_alarm;
    pe_register_vtbl(vt, gv_stashpv("Event::Watcher::Tied",1), &event_vtbl);
}