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.323 by root, Sat Nov 22 06:03:10 2008 UTC vs.
Revision 1.326 by root, Mon Nov 24 04:56:38 2008 UTC

175static HV *coro_state_stash, *coro_stash; 175static HV *coro_state_stash, *coro_stash;
176static volatile SV *coro_mortal; /* will be freed/thrown after next transfer */ 176static volatile SV *coro_mortal; /* will be freed/thrown after next transfer */
177 177
178static AV *av_destroy; /* destruction queue */ 178static AV *av_destroy; /* destruction queue */
179static SV *sv_manager; /* the manager coro */ 179static SV *sv_manager; /* the manager coro */
180static SV *sv_idle; /* $Coro::idle */
180 181
181static GV *irsgv; /* $/ */ 182static GV *irsgv; /* $/ */
182static GV *stdoutgv; /* *STDOUT */ 183static GV *stdoutgv; /* *STDOUT */
183static SV *rv_diehook; 184static SV *rv_diehook;
184static SV *rv_warnhook; 185static SV *rv_warnhook;
1329 /* TODO: throwing up here is considered harmful */ 1330 /* TODO: throwing up here is considered harmful */
1330 1331
1331 if (expect_true (prev != next)) 1332 if (expect_true (prev != next))
1332 { 1333 {
1333 if (expect_false (!(prev->flags & (CF_RUNNING | CF_NEW)))) 1334 if (expect_false (!(prev->flags & (CF_RUNNING | CF_NEW))))
1334 croak ("Coro::State::transfer called with non-running/new prev Coro::State, but can only transfer from running or new states,"); 1335 croak ("Coro::State::transfer called with a suspended prev Coro::State, but can only transfer from running or new states,");
1335 1336
1336 if (expect_false (next->flags & CF_RUNNING)) 1337 if (expect_false (next->flags & CF_RUNNING))
1337 croak ("Coro::State::transfer called with running next Coro::State, but can only transfer to inactive states,"); 1338 croak ("Coro::State::transfer called with running next Coro::State, but can only transfer to inactive states,");
1338 1339
1339 if (expect_false (next->flags & CF_DESTROYED)) 1340 if (expect_false (next->flags & CF_DESTROYED))
1383 coro_setup (aTHX_ next); 1384 coro_setup (aTHX_ next);
1384 } 1385 }
1385 else 1386 else
1386 load_perl (aTHX_ next); 1387 load_perl (aTHX_ next);
1387 1388
1389 assert (!prev->cctx);//D temporary
1390
1388 /* possibly untie and reuse the cctx */ 1391 /* possibly untie and reuse the cctx */
1389 if (expect_true ( 1392 if (expect_true (
1390 cctx_current->idle_sp == STACKLEVEL 1393 cctx_current->idle_sp == STACKLEVEL
1391 && !(cctx_current->flags & CC_TRACE) 1394 && !(cctx_current->flags & CC_TRACE)
1392 && !force_cctx 1395 && !force_cctx
1393 )) 1396 ))
1394 { 1397 {
1395 /* I assume that stacklevel is a stronger indicator than PL_top_env changes */ 1398 /* I assume that stacklevel is a stronger indicator than PL_top_env changes */
1396 assert (("FATAL: current top_env must equal previous top_env in Coro (please report)", PL_top_env == cctx_current->idle_te)); 1399 assert (("FATAL: current top_env must equal previous top_env in Coro (please report)", PL_top_env == cctx_current->idle_te));
1397 1400
1398 /* if the cctx is about to be destroyed we need to make sure we won't see it in cctx_get */ 1401 /* if the cctx is about to be destroyed we need to make sure we won't see it in cctx_get. */
1399 /* without this the next cctx_get might destroy the prev__cctx while still in use */ 1402 /* without this the next cctx_get might destroy the running cctx while still in use */
1400 if (expect_false (CCTX_EXPIRED (cctx_current))) 1403 if (expect_false (CCTX_EXPIRED (cctx_current)))
1401 if (!next->cctx) 1404 if (expect_true (!next->cctx))
1402 next->cctx = cctx_get (aTHX); 1405 next->cctx = cctx_get (aTHX);
1403 1406
1404 cctx_put (cctx_current); 1407 cctx_put (cctx_current);
1405 assert (!prev->cctx);//D temporary
1406 } 1408 }
1407 else 1409 else
1408 prev->cctx = cctx_current; 1410 prev->cctx = cctx_current;
1409 1411
1410 ++next->usecount; 1412 ++next->usecount;
1581{ 1583{
1582 struct coro *coro; 1584 struct coro *coro;
1583 SV *sv_hook; 1585 SV *sv_hook;
1584 void (*xs_hook)(void); 1586 void (*xs_hook)(void);
1585 1587
1586 if (SvROK (coro_sv))
1587 coro_sv = SvRV (coro_sv);
1588
1589 coro = SvSTATE (coro_sv); 1588 coro = SvSTATE (coro_sv);
1590 1589
1591 if (coro->flags & CF_READY) 1590 if (coro->flags & CF_READY)
1592 return 0; 1591 return 0;
1593 1592
1667 } 1666 }
1668 } 1667 }
1669 else 1668 else
1670 { 1669 {
1671 /* nothing to schedule: call the idle handler */ 1670 /* nothing to schedule: call the idle handler */
1671 if (SvROK (sv_idle)
1672 && SvOBJECT (SvRV (sv_idle)))
1673 {
1674 ++coro_nready; /* hack so that api_ready doesn't invoke ready hook */
1675 api_ready (SvRV (sv_idle));
1676 --coro_nready;
1677 }
1678 else
1679 {
1672 dSP; 1680 dSP;
1673 1681
1674 ENTER; 1682 ENTER;
1675 SAVETMPS; 1683 SAVETMPS;
1676 1684
1677 PUSHMARK (SP); 1685 PUSHMARK (SP);
1678 PUTBACK; 1686 PUTBACK;
1679 call_sv (get_sv ("Coro::idle", FALSE), G_VOID | G_DISCARD); 1687 call_sv (sv_idle, G_VOID | G_DISCARD);
1680 1688
1681 FREETMPS; 1689 FREETMPS;
1682 LEAVE; 1690 LEAVE;
1691 }
1683 } 1692 }
1684 } 1693 }
1685} 1694}
1686 1695
1687INLINE void 1696INLINE void
1758static void 1767static void
1759api_trace (pTHX_ SV *coro_sv, int flags) 1768api_trace (pTHX_ SV *coro_sv, int flags)
1760{ 1769{
1761 struct coro *coro = SvSTATE (coro_sv); 1770 struct coro *coro = SvSTATE (coro_sv);
1762 1771
1772 if (coro->flags & CF_RUNNING)
1773 croak ("cannot enable tracing on a running coroutine, caught");
1774
1763 if (flags & CC_TRACE) 1775 if (flags & CC_TRACE)
1764 { 1776 {
1765 if (!coro->cctx) 1777 if (!coro->cctx)
1766 coro->cctx = cctx_new_run (); 1778 coro->cctx = cctx_new_run ();
1767 else if (!(coro->cctx->flags & CC_TRACE)) 1779 else if (!(coro->cctx->flags & CC_TRACE))
1768 croak ("cannot enable tracing on coroutine with custom stack,"); 1780 croak ("cannot enable tracing on coroutine with custom stack, caught");
1769 1781
1770 coro->cctx->flags |= CC_NOREUSE | (flags & (CC_TRACE | CC_TRACE_ALL)); 1782 coro->cctx->flags |= CC_NOREUSE | (flags & (CC_TRACE | CC_TRACE_ALL));
1771 } 1783 }
1772 else if (coro->cctx && coro->cctx->flags & CC_TRACE) 1784 else if (coro->cctx && coro->cctx->flags & CC_TRACE)
1773 { 1785 {
3094 cv_coro_terminate = get_cv ( "Coro::terminate" , GV_ADD); 3106 cv_coro_terminate = get_cv ( "Coro::terminate" , GV_ADD);
3095 coro_current = coro_get_sv (aTHX_ "Coro::current" , FALSE); SvREADONLY_on (coro_current); 3107 coro_current = coro_get_sv (aTHX_ "Coro::current" , FALSE); SvREADONLY_on (coro_current);
3096 av_async_pool = coro_get_av (aTHX_ "Coro::async_pool", TRUE); 3108 av_async_pool = coro_get_av (aTHX_ "Coro::async_pool", TRUE);
3097 av_destroy = coro_get_av (aTHX_ "Coro::destroy" , TRUE); 3109 av_destroy = coro_get_av (aTHX_ "Coro::destroy" , TRUE);
3098 sv_manager = coro_get_sv (aTHX_ "Coro::manager" , TRUE); 3110 sv_manager = coro_get_sv (aTHX_ "Coro::manager" , TRUE);
3111 sv_idle = coro_get_sv (aTHX_ "Coro::idle" , TRUE);
3099 3112
3100 sv_async_pool_idle = newSVpv ("[async pool idle]", 0); SvREADONLY_on (sv_async_pool_idle); 3113 sv_async_pool_idle = newSVpv ("[async pool idle]", 0); SvREADONLY_on (sv_async_pool_idle);
3101 sv_Coro = newSVpv ("Coro", 0); SvREADONLY_on (sv_Coro); 3114 sv_Coro = newSVpv ("Coro", 0); SvREADONLY_on (sv_Coro);
3102 cv_pool_handler = get_cv ("Coro::pool_handler", GV_ADD); SvREADONLY_on (cv_pool_handler); 3115 cv_pool_handler = get_cv ("Coro::pool_handler", GV_ADD); SvREADONLY_on (cv_pool_handler);
3103 cv_coro_state_new = get_cv ("Coro::State::new", 0); SvREADONLY_on (cv_coro_state_new); 3116 cv_coro_state_new = get_cv ("Coro::State::new", 0); SvREADONLY_on (cv_coro_state_new);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines