… | |
… | |
283 | static struct coro *coro_ready [CORO_PRIO_MAX - CORO_PRIO_MIN + 1][2]; /* head|tail */ |
283 | static struct coro *coro_ready [CORO_PRIO_MAX - CORO_PRIO_MIN + 1][2]; /* head|tail */ |
284 | static CV *cv_coro_run, *cv_coro_terminate; |
284 | static CV *cv_coro_run, *cv_coro_terminate; |
285 | static struct coro *coro_first; |
285 | static struct coro *coro_first; |
286 | #define coro_nready coroapi.nready |
286 | #define coro_nready coroapi.nready |
287 | |
287 | |
|
|
288 | /** Coro::Select ************************************************************/ |
|
|
289 | |
|
|
290 | static OP *(*coro_old_pp_sselect) (pTHX); |
|
|
291 | static SV *coro_select_select; |
|
|
292 | |
|
|
293 | /* horrible hack, but if it works... */ |
|
|
294 | static OP * |
|
|
295 | coro_pp_sselect (aTHX) |
|
|
296 | { |
|
|
297 | dSP; |
|
|
298 | PUSHMARK (SP - 4); /* fake argument list */ |
|
|
299 | XPUSHs (coro_select_select); |
|
|
300 | PUTBACK; |
|
|
301 | |
|
|
302 | /* entersub is an UNOP, select a LISTOP... keep your fingers crossed */ |
|
|
303 | PL_op->op_flags |= OPf_STACKED; |
|
|
304 | PL_op->op_private = 0; |
|
|
305 | return PL_ppaddr [OP_ENTERSUB](aTHX); |
|
|
306 | } |
|
|
307 | |
288 | /** lowlevel stuff **********************************************************/ |
308 | /** lowlevel stuff **********************************************************/ |
289 | |
309 | |
290 | static SV * |
310 | static SV * |
291 | coro_get_sv (pTHX_ const char *name, int create) |
311 | coro_get_sv (pTHX_ const char *name, int create) |
292 | { |
312 | { |
… | |
… | |
1255 | /* somebody or something will hit me for both perl_run and PL_restartop */ |
1275 | /* somebody or something will hit me for both perl_run and PL_restartop */ |
1256 | PL_restartop = PL_op; |
1276 | PL_restartop = PL_op; |
1257 | perl_run (PL_curinterp); |
1277 | perl_run (PL_curinterp); |
1258 | /* |
1278 | /* |
1259 | * Unfortunately, there is no way to get at the return values of the |
1279 | * Unfortunately, there is no way to get at the return values of the |
1260 | * coro body here, as perl_run destroys these |
1280 | * coro body here, as perl_run destroys these. Likewise, we cannot catch |
|
|
1281 | * runtime errors here, as this is just a random interpreter, not a thread. |
1261 | */ |
1282 | */ |
1262 | |
1283 | |
1263 | /* |
1284 | /* |
1264 | * If perl-run returns we assume exit() was being called or the coro |
1285 | * If perl-run returns we assume exit() was being called or the coro |
1265 | * fell off the end, which seems to be the only valid (non-bug) |
1286 | * fell off the end, which seems to be the only valid (non-bug) |
… | |
… | |
1648 | } |
1669 | } |
1649 | |
1670 | |
1650 | return 0; |
1671 | return 0; |
1651 | } |
1672 | } |
1652 | |
1673 | |
|
|
1674 | static void |
|
|
1675 | invoke_sv_ready_hook_helper (void) |
|
|
1676 | { |
|
|
1677 | dTHX; |
|
|
1678 | dSP; |
|
|
1679 | |
|
|
1680 | ENTER; |
|
|
1681 | SAVETMPS; |
|
|
1682 | |
|
|
1683 | PUSHMARK (SP); |
|
|
1684 | PUTBACK; |
|
|
1685 | call_sv (coro_readyhook, G_VOID | G_DISCARD); |
|
|
1686 | |
|
|
1687 | FREETMPS; |
|
|
1688 | LEAVE; |
|
|
1689 | } |
|
|
1690 | |
1653 | static int |
1691 | static int |
1654 | api_ready (pTHX_ SV *coro_sv) |
1692 | api_ready (pTHX_ SV *coro_sv) |
1655 | { |
1693 | { |
1656 | struct coro *coro; |
|
|
1657 | SV *sv_hook; |
|
|
1658 | void (*xs_hook)(void); |
|
|
1659 | |
|
|
1660 | coro = SvSTATE (coro_sv); |
1694 | struct coro *coro = SvSTATE (coro_sv); |
1661 | |
1695 | |
1662 | if (coro->flags & CF_READY) |
1696 | if (coro->flags & CF_READY) |
1663 | return 0; |
1697 | return 0; |
1664 | |
1698 | |
1665 | coro->flags |= CF_READY; |
1699 | coro->flags |= CF_READY; |
1666 | |
1700 | |
1667 | sv_hook = coro_nready ? 0 : coro_readyhook; |
|
|
1668 | xs_hook = coro_nready ? 0 : coroapi.readyhook; |
|
|
1669 | |
|
|
1670 | coro_enq (aTHX_ coro); |
1701 | coro_enq (aTHX_ coro); |
1671 | ++coro_nready; |
|
|
1672 | |
1702 | |
1673 | if (sv_hook) |
1703 | if (!coro_nready++) |
1674 | { |
1704 | if (coroapi.readyhook) |
1675 | dSP; |
1705 | coroapi.readyhook (); |
1676 | |
|
|
1677 | ENTER; |
|
|
1678 | SAVETMPS; |
|
|
1679 | |
|
|
1680 | PUSHMARK (SP); |
|
|
1681 | PUTBACK; |
|
|
1682 | call_sv (sv_hook, G_VOID | G_DISCARD); |
|
|
1683 | |
|
|
1684 | FREETMPS; |
|
|
1685 | LEAVE; |
|
|
1686 | } |
|
|
1687 | |
|
|
1688 | if (xs_hook) |
|
|
1689 | xs_hook (); |
|
|
1690 | |
1706 | |
1691 | return 1; |
1707 | return 1; |
1692 | } |
1708 | } |
1693 | |
1709 | |
1694 | static int |
1710 | static int |
… | |
… | |
3374 | _set_readyhook (SV *hook) |
3390 | _set_readyhook (SV *hook) |
3375 | PROTOTYPE: $ |
3391 | PROTOTYPE: $ |
3376 | CODE: |
3392 | CODE: |
3377 | SvREFCNT_dec (coro_readyhook); |
3393 | SvREFCNT_dec (coro_readyhook); |
3378 | SvGETMAGIC (hook); |
3394 | SvGETMAGIC (hook); |
|
|
3395 | if (SvOK (hook)) |
|
|
3396 | { |
3379 | coro_readyhook = SvOK (hook) ? newSVsv (hook) : 0; |
3397 | coro_readyhook = newSVsv (hook); |
|
|
3398 | CORO_READYHOOK = invoke_sv_ready_hook_helper; |
|
|
3399 | } |
|
|
3400 | else |
|
|
3401 | { |
|
|
3402 | coro_readyhook = 0; |
|
|
3403 | CORO_READYHOOK = 0; |
|
|
3404 | } |
3380 | |
3405 | |
3381 | int |
3406 | int |
3382 | prio (Coro::State coro, int newprio = 0) |
3407 | prio (Coro::State coro, int newprio = 0) |
3383 | PROTOTYPE: $;$ |
3408 | PROTOTYPE: $;$ |
3384 | ALIAS: |
3409 | ALIAS: |
… | |
… | |
3717 | CV *slf_cv = newXS (target, coro_aio_req_xs, __FILE__); |
3742 | CV *slf_cv = newXS (target, coro_aio_req_xs, __FILE__); |
3718 | sv_setpv ((SV *)slf_cv, proto); |
3743 | sv_setpv ((SV *)slf_cv, proto); |
3719 | sv_magicext ((SV *)slf_cv, (SV *)req_cv, CORO_MAGIC_type_aio, 0, 0, 0); |
3744 | sv_magicext ((SV *)slf_cv, (SV *)req_cv, CORO_MAGIC_type_aio, 0, 0, 0); |
3720 | } |
3745 | } |
3721 | |
3746 | |
|
|
3747 | MODULE = Coro::State PACKAGE = Coro::Select |
|
|
3748 | |
|
|
3749 | void |
|
|
3750 | patch_pp_sselect () |
|
|
3751 | CODE: |
|
|
3752 | if (!coro_old_pp_sselect) |
|
|
3753 | { |
|
|
3754 | coro_select_select = (SV *)get_cv ("Coro::Select::select", 0); |
|
|
3755 | coro_old_pp_sselect = PL_ppaddr [OP_SSELECT]; |
|
|
3756 | PL_ppaddr [OP_SSELECT] = coro_pp_sselect; |
|
|
3757 | } |
|
|
3758 | |
|
|
3759 | void |
|
|
3760 | unpatch_pp_sselect () |
|
|
3761 | CODE: |
|
|
3762 | if (coro_old_pp_sselect) |
|
|
3763 | { |
|
|
3764 | PL_ppaddr [OP_SSELECT] = coro_old_pp_sselect; |
|
|
3765 | coro_old_pp_sselect = 0; |
|
|
3766 | } |
|
|
3767 | |
|
|
3768 | |