ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro/Coro/State.xs
(Generate patch)

Comparing Coro/Coro/State.xs (file contents):
Revision 1.363 by root, Tue Jul 14 00:55:10 2009 UTC vs.
Revision 1.367 by root, Mon Aug 3 09:19:57 2009 UTC

283static struct coro *coro_ready [CORO_PRIO_MAX - CORO_PRIO_MIN + 1][2]; /* head|tail */ 283static struct coro *coro_ready [CORO_PRIO_MAX - CORO_PRIO_MIN + 1][2]; /* head|tail */
284static CV *cv_coro_run, *cv_coro_terminate; 284static CV *cv_coro_run, *cv_coro_terminate;
285static struct coro *coro_first; 285static struct coro *coro_first;
286#define coro_nready coroapi.nready 286#define coro_nready coroapi.nready
287 287
288/** Coro::Select ************************************************************/
289
290static OP *(*coro_old_pp_sselect) (pTHX);
291static SV *coro_select_select;
292
293/* horrible hack, but if it works... */
294static OP *
295coro_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
290static SV * 310static SV *
291coro_get_sv (pTHX_ const char *name, int create) 311coro_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
1674static void
1675invoke_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
1653static int 1691static int
1654api_ready (pTHX_ SV *coro_sv) 1692api_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
1694static int 1710static 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
3381int 3406int
3382prio (Coro::State coro, int newprio = 0) 3407prio (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
3747MODULE = Coro::State PACKAGE = Coro::Select
3748
3749void
3750patch_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
3759void
3760unpatch_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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines