… | |
… | |
23 | #define EV_NONE 0 |
23 | #define EV_NONE 0 |
24 | #define EV_UNDEF -1 |
24 | #define EV_UNDEF -1 |
25 | |
25 | |
26 | #define TIMEOUT_NONE HUGE_VAL |
26 | #define TIMEOUT_NONE HUGE_VAL |
27 | |
27 | |
|
|
28 | #include "EV/EVAPI.h" |
|
|
29 | |
28 | typedef struct event_base *Base; |
30 | typedef struct event_base *Base; |
29 | typedef int Signal; |
31 | typedef int Signal; |
|
|
32 | |
|
|
33 | static struct EVAPI evapi; |
30 | |
34 | |
31 | static HV *stash_base, *stash_event; |
35 | static HV *stash_base, *stash_event; |
32 | |
36 | |
33 | static double tv_get (struct timeval *tv) |
37 | static double tv_get (struct timeval *tv) |
34 | { |
38 | { |
… | |
… | |
53 | for (signum = 1; signum < SIG_SIZE; ++signum) |
57 | for (signum = 1; signum < SIG_SIZE; ++signum) |
54 | if (strEQ (SvPV_nolen (sig), PL_sig_name [signum])) |
58 | if (strEQ (SvPV_nolen (sig), PL_sig_name [signum])) |
55 | return signum; |
59 | return signum; |
56 | |
60 | |
57 | return -1; |
61 | return -1; |
|
|
62 | } |
|
|
63 | |
|
|
64 | static void |
|
|
65 | api_once (int fd, short events, double timeout, void (*cb)(int, short, void *), void *arg) |
|
|
66 | { |
|
|
67 | if (timeout >= 0.) |
|
|
68 | { |
|
|
69 | struct timeval tv; |
|
|
70 | tv_set (&tv, timeout); |
|
|
71 | event_once (fd, events, cb, arg, &tv); |
|
|
72 | } |
|
|
73 | else |
|
|
74 | event_once (fd, events, cb, arg, 0); |
58 | } |
75 | } |
59 | |
76 | |
60 | ///////////////////////////////////////////////////////////////////////////// |
77 | ///////////////////////////////////////////////////////////////////////////// |
61 | // Event |
78 | // Event |
62 | |
79 | |
… | |
… | |
69 | unsigned char active; |
86 | unsigned char active; |
70 | unsigned char abstime; |
87 | unsigned char abstime; |
71 | } *Event; |
88 | } *Event; |
72 | |
89 | |
73 | static double |
90 | static double |
74 | e_now () |
91 | e_now (void) |
75 | { |
92 | { |
76 | struct timeval tv; |
93 | struct timeval tv; |
77 | gettimeofday (&tv, 0); |
94 | gettimeofday (&tv, 0); |
78 | |
95 | |
79 | return tv_get (&tv); |
96 | return tv_get (&tv); |
… | |
… | |
181 | static void |
198 | static void |
182 | e_cb (int fd, short events, void *arg) |
199 | e_cb (int fd, short events, void *arg) |
183 | { |
200 | { |
184 | struct ev *ev = (struct ev*)arg; |
201 | struct ev *ev = (struct ev*)arg; |
185 | dSP; |
202 | dSP; |
186 | |
203 | I32 mark = SP - PL_stack_base; |
187 | ENTER; |
204 | SV *sv_self, *sv_events; |
188 | SAVETMPS; |
205 | static SV *sv_events_cache; |
189 | |
206 | |
190 | if (!(ev->ev.ev_events & EV_PERSIST) || (events & EV_TIMEOUT)) |
207 | if (!(ev->ev.ev_events & EV_PERSIST) || (events & EV_TIMEOUT)) |
191 | ev->active = 0; |
208 | ev->active = 0; |
192 | |
209 | |
|
|
210 | sv_self = e_self (ev); |
|
|
211 | |
|
|
212 | if (sv_events_cache) |
|
|
213 | { |
|
|
214 | sv_events = sv_events_cache; sv_events_cache = 0; |
|
|
215 | SvIV_set (sv_events, events); |
|
|
216 | } |
|
|
217 | else |
|
|
218 | sv_events = newSViv (events); |
|
|
219 | |
193 | PUSHMARK (SP); |
220 | PUSHMARK (SP); |
194 | EXTEND (SP, 2); |
221 | EXTEND (SP, 2); |
195 | PUSHs (sv_2mortal (e_self (ev))); |
222 | PUSHs (sv_self); |
196 | PUSHs (sv_2mortal (newSViv (events))); |
223 | PUSHs (sv_events); |
197 | PUTBACK; |
224 | PUTBACK; |
198 | call_sv (ev->cb, G_DISCARD | G_VOID | G_EVAL); |
225 | call_sv (ev->cb, G_DISCARD | G_VOID | G_EVAL); |
|
|
226 | SP = PL_stack_base + mark; PUTBACK; |
|
|
227 | |
|
|
228 | SvREFCNT_dec (sv_self); |
|
|
229 | |
|
|
230 | if (sv_events_cache) |
|
|
231 | SvREFCNT_dec (sv_events); |
|
|
232 | else |
|
|
233 | sv_events_cache = sv_events; |
199 | |
234 | |
200 | if (ev->interval && !ev->active) |
235 | if (ev->interval && !ev->active) |
201 | e_start (ev); |
236 | e_start (ev); |
202 | |
|
|
203 | FREETMPS; |
|
|
204 | |
237 | |
205 | if (SvTRUE (ERRSV)) |
238 | if (SvTRUE (ERRSV)) |
206 | { |
239 | { |
207 | PUSHMARK (SP); |
240 | PUSHMARK (SP); |
208 | PUTBACK; |
241 | PUTBACK; |
209 | call_sv (get_sv ("EV::DIED", 1), G_DISCARD | G_VOID | G_EVAL | G_KEEPERR); |
242 | call_sv (get_sv ("EV::DIED", 1), G_DISCARD | G_VOID | G_EVAL | G_KEEPERR); |
|
|
243 | SP = PL_stack_base + mark; PUTBACK; |
210 | } |
244 | } |
211 | |
|
|
212 | LEAVE; |
|
|
213 | } |
245 | } |
214 | |
246 | |
215 | ///////////////////////////////////////////////////////////////////////////// |
247 | ///////////////////////////////////////////////////////////////////////////// |
216 | // DNS |
248 | // DNS |
217 | |
249 | |
… | |
… | |
297 | for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; ) |
329 | for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; ) |
298 | newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv)); |
330 | newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv)); |
299 | |
331 | |
300 | stash_base = gv_stashpv ("EV::Base" , 1); |
332 | stash_base = gv_stashpv ("EV::Base" , 1); |
301 | stash_event = gv_stashpv ("EV::Event", 1); |
333 | stash_event = gv_stashpv ("EV::Event", 1); |
|
|
334 | |
|
|
335 | { |
|
|
336 | SV *sv = perl_get_sv ("EV::API", TRUE); |
|
|
337 | perl_get_sv ("EV::API", TRUE); /* silence 5.10 warning */ |
|
|
338 | |
|
|
339 | evapi.ver = EV_API_VERSION; |
|
|
340 | evapi.rev = EV_API_REVISION; |
|
|
341 | evapi.now = e_now; |
|
|
342 | evapi.once = api_once; |
|
|
343 | evapi.loop = event_loop; |
|
|
344 | |
|
|
345 | sv_setiv (sv, (IV)&evapi); |
|
|
346 | SvREADONLY_on (sv); |
|
|
347 | } |
302 | } |
348 | } |
303 | |
349 | |
304 | double now () |
350 | double now () |
305 | CODE: |
351 | CODE: |
306 | RETVAL = e_now (); |
352 | RETVAL = e_now (); |