… | |
… | |
84 | typedef struct { |
84 | typedef struct { |
85 | SV *cb; |
85 | SV *cb; |
86 | void (*c_cb)(pTHX_ void *c_arg, int value); |
86 | void (*c_cb)(pTHX_ void *c_arg, int value); |
87 | void *c_arg; |
87 | void *c_arg; |
88 | SV *fh_r, *fh_w; |
88 | SV *fh_r, *fh_w; |
89 | int blocked; |
|
|
90 | int signum; |
89 | int signum; |
|
|
90 | volatile int blocked; |
91 | |
91 | |
92 | int fd_r, fd_w; |
92 | int fd_r; |
|
|
93 | volatile int fd_w; |
93 | int fd_wlen; |
94 | int fd_wlen; |
94 | atomic_t fd_enable; |
95 | atomic_t fd_enable; |
95 | atomic_t value; |
96 | atomic_t value; |
96 | atomic_t pending; |
97 | atomic_t pending; |
97 | } async_t; |
98 | } async_t; |
… | |
… | |
115 | async->pending = 1; |
116 | async->pending = 1; |
116 | async_pending = 1; |
117 | async_pending = 1; |
117 | psig_pend [9] = 1; |
118 | psig_pend [9] = 1; |
118 | *sig_pending = 1; |
119 | *sig_pending = 1; |
119 | |
120 | |
|
|
121 | { |
|
|
122 | int fd_w = async->fd_w; |
|
|
123 | int fd_enable = async->fd_enable; |
|
|
124 | |
120 | if (!pending && async->fd_w >= 0 && async->fd_enable) |
125 | if (!pending && fd_w >= 0 && fd_enable) |
121 | if (write (async->fd_w, pipedata, async->fd_wlen) < 0 && errno == EINVAL) |
126 | if (write (fd_w, pipedata, async->fd_wlen) < 0 && errno == EINVAL) |
122 | /* on EINVAL we assume it's an eventfd */ |
127 | /* on EINVAL we assume it's an eventfd */ |
123 | write (async->fd_w, pipedata, (async->fd_wlen = 8)); |
128 | write (fd_w, pipedata, (async->fd_wlen = 8)); |
|
|
129 | } |
124 | } |
130 | } |
125 | |
131 | |
126 | static void |
132 | static void |
127 | handle_async (async_t *async) |
133 | handle_async (async_t *async) |
128 | { |
134 | { |
… | |
… | |
226 | async_sigsend (int signum) |
232 | async_sigsend (int signum) |
227 | { |
233 | { |
228 | async_signal (sig_async [signum], 0); |
234 | async_signal (sig_async [signum], 0); |
229 | } |
235 | } |
230 | |
236 | |
231 | static void |
237 | #define block(async) ++(async)->blocked |
232 | scope_block_cb (pTHX_ void *async_sv) |
|
|
233 | { |
|
|
234 | async_t *async = SvASYNC_nrv ((SV *)async_sv); |
|
|
235 | |
238 | |
|
|
239 | static void |
|
|
240 | unblock (async_t *async) |
|
|
241 | { |
236 | --async->blocked; |
242 | --async->blocked; |
237 | if (async->pending && !async->blocked) |
243 | if (async->pending && !async->blocked) |
238 | handle_async (async); |
244 | handle_async (async); |
|
|
245 | } |
239 | |
246 | |
|
|
247 | static void |
|
|
248 | scope_block_cb (pTHX_ void *async_sv) |
|
|
249 | { |
|
|
250 | async_t *async = SvASYNC_nrv ((SV *)async_sv); |
|
|
251 | unblock (async); |
240 | SvREFCNT_dec (async_sv); |
252 | SvREFCNT_dec (async_sv); |
241 | } |
253 | } |
242 | |
254 | |
243 | MODULE = Async::Interrupt PACKAGE = Async::Interrupt |
255 | MODULE = Async::Interrupt PACKAGE = Async::Interrupt |
244 | |
256 | |
… | |
… | |
308 | async_signal (async, value); |
320 | async_signal (async, value); |
309 | |
321 | |
310 | void |
322 | void |
311 | block (async_t *async) |
323 | block (async_t *async) |
312 | CODE: |
324 | CODE: |
313 | ++async->blocked; |
325 | block (async); |
314 | |
326 | |
315 | void |
327 | void |
316 | unblock (async_t *async) |
328 | unblock (async_t *async) |
317 | CODE: |
329 | CODE: |
318 | --async->blocked; |
330 | unblock (async); |
319 | if (async->pending && !async->blocked) |
|
|
320 | handle_async (async); |
|
|
321 | |
331 | |
322 | void |
332 | void |
323 | scope_block (SV *self) |
333 | scope_block (SV *self) |
324 | CODE: |
334 | CODE: |
325 | { |
335 | { |
326 | SV *async_sv = SvRV (self); |
336 | SV *async_sv = SvRV (self); |
327 | async_t *async = SvASYNC_nrv (async_sv); |
337 | async_t *async = SvASYNC_nrv (async_sv); |
328 | ++async->blocked; |
338 | block (async); |
329 | |
339 | |
330 | LEAVE; /* unfortunately, perl sandwiches XS calls into ENTER/LEAVE */ |
340 | LEAVE; /* unfortunately, perl sandwiches XS calls into ENTER/LEAVE */ |
331 | SAVEDESTRUCTOR_X (scope_block_cb, (void *)SvREFCNT_inc (async_sv)); |
341 | SAVEDESTRUCTOR_X (scope_block_cb, (void *)SvREFCNT_inc (async_sv)); |
332 | ENTER; /* unfortunately, perl sandwiches XS calls into ENTER/LEAVE */ |
342 | ENTER; /* unfortunately, perl sandwiches XS calls into ENTER/LEAVE */ |
333 | } |
343 | } |