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.314 by root, Thu Nov 20 03:24:39 2008 UTC vs.
Revision 1.316 by root, Thu Nov 20 06:01:40 2008 UTC

183static SV *sv_pool_size; 183static SV *sv_pool_size;
184static SV *sv_async_pool_idle; 184static SV *sv_async_pool_idle;
185static AV *av_async_pool; 185static AV *av_async_pool;
186static SV *sv_Coro; 186static SV *sv_Coro;
187static CV *cv_pool_handler; 187static CV *cv_pool_handler;
188static CV *cv_coro_new; 188static CV *cv_coro_state_new;
189 189
190/* Coro::AnyEvent */ 190/* Coro::AnyEvent */
191static SV *sv_activity; 191static SV *sv_activity;
192 192
193static struct coro_cctx *cctx_first; 193static struct coro_cctx *cctx_first;
1612api_is_ready (pTHX_ SV *coro_sv) 1612api_is_ready (pTHX_ SV *coro_sv)
1613{ 1613{
1614 return !!(SvSTATE (coro_sv)->flags & CF_READY); 1614 return !!(SvSTATE (coro_sv)->flags & CF_READY);
1615} 1615}
1616 1616
1617/* expects to own a reference to next->hv */
1617INLINE void 1618INLINE void
1619prepare_cede_to (pTHX_ struct coro_transfer_args *ta, struct coro *next)
1620{
1621 SV *prev_sv = SvRV (coro_current);
1622
1623 ta->prev = SvSTATE_hv (prev_sv);
1624 ta->next = next;
1625
1626 TRANSFER_CHECK (*ta);
1627
1628 SvRV_set (coro_current, next->hv);
1629
1630 free_coro_mortal (aTHX);
1631 coro_mortal = prev_sv;
1632}
1633
1634static void
1618prepare_schedule (pTHX_ struct coro_transfer_args *ta) 1635prepare_schedule (pTHX_ struct coro_transfer_args *ta)
1619{ 1636{
1620 SV *prev_sv, *next_sv;
1621
1622 for (;;) 1637 for (;;)
1623 { 1638 {
1624 next_sv = coro_deq (aTHX); 1639 SV *next_sv = coro_deq (aTHX);
1625 1640
1626 /* nothing to schedule: call the idle handler */
1627 if (expect_false (!next_sv)) 1641 if (expect_false (!next_sv))
1628 { 1642 {
1643 /* nothing to schedule: call the idle handler */
1629 dSP; 1644 dSP;
1630 1645
1631 ENTER; 1646 ENTER;
1632 SAVETMPS; 1647 SAVETMPS;
1633 1648
1635 PUTBACK; 1650 PUTBACK;
1636 call_sv (get_sv ("Coro::idle", FALSE), G_VOID | G_DISCARD); 1651 call_sv (get_sv ("Coro::idle", FALSE), G_VOID | G_DISCARD);
1637 1652
1638 FREETMPS; 1653 FREETMPS;
1639 LEAVE; 1654 LEAVE;
1640 continue;
1641 } 1655 }
1642 1656 else
1643 ta->next = SvSTATE_hv (next_sv);
1644
1645 /* cannot transfer to destroyed coros, skip and look for next */
1646 if (expect_false (ta->next->flags & CF_DESTROYED))
1647 { 1657 {
1648 SvREFCNT_dec (next_sv); 1658 struct coro *next = SvSTATE_hv (next_sv);
1659
1660 /* cannot transfer to destroyed coros, skip and look for next */
1661 if (expect_false (next->flags & CF_DESTROYED))
1649 /* coro_nready has already been taken care of by destroy */ 1662 SvREFCNT_dec (next_sv); /* coro_nready has already been taken care of by destroy */
1650 continue; 1663 else
1664 {
1665 next->flags &= ~CF_READY;
1666 --coro_nready;
1667
1668 return prepare_cede_to (aTHX_ ta, next);
1669 }
1651 } 1670 }
1652
1653 --coro_nready;
1654 break;
1655 } 1671 }
1656
1657 /* free this only after the transfer */
1658 prev_sv = SvRV (coro_current);
1659 ta->prev = SvSTATE_hv (prev_sv);
1660 TRANSFER_CHECK (*ta);
1661 assert (("FATAL: next coroutine isn't marked as ready in Coro (please report)", ta->next->flags & CF_READY));
1662 ta->next->flags &= ~CF_READY;
1663 SvRV_set (coro_current, next_sv);
1664
1665 free_coro_mortal (aTHX);
1666 coro_mortal = prev_sv;
1667} 1672}
1668 1673
1669INLINE void 1674INLINE void
1670prepare_cede (pTHX_ struct coro_transfer_args *ta) 1675prepare_cede (pTHX_ struct coro_transfer_args *ta)
1671{ 1676{
2957 2962
2958 av_async_pool = coro_get_av (aTHX_ "Coro::async_pool", TRUE); 2963 av_async_pool = coro_get_av (aTHX_ "Coro::async_pool", TRUE);
2959 sv_pool_rss = coro_get_sv (aTHX_ "Coro::POOL_RSS" , TRUE); 2964 sv_pool_rss = coro_get_sv (aTHX_ "Coro::POOL_RSS" , TRUE);
2960 sv_pool_size = coro_get_sv (aTHX_ "Coro::POOL_SIZE" , TRUE); 2965 sv_pool_size = coro_get_sv (aTHX_ "Coro::POOL_SIZE" , TRUE);
2961 cv_coro_run = get_cv ( "Coro::_terminate", GV_ADD); 2966 cv_coro_run = get_cv ( "Coro::_terminate", GV_ADD);
2962 cv_coro_terminate = get_cv ( "Coro::terminate", GV_ADD); 2967 cv_coro_terminate = get_cv ( "Coro::terminate" , GV_ADD);
2963 coro_current = coro_get_sv (aTHX_ "Coro::current" , FALSE); 2968 coro_current = coro_get_sv (aTHX_ "Coro::current" , FALSE); SvREADONLY_on (coro_current);
2964 SvREADONLY_on (coro_current);
2965 2969
2966 sv_async_pool_idle = newSVpv ("[async pool idle]", 0); SvREADONLY_on (sv_async_pool_idle); 2970 sv_async_pool_idle = newSVpv ("[async pool idle]", 0); SvREADONLY_on (sv_async_pool_idle);
2967 sv_Coro = newSVpv ("Coro", 0); SvREADONLY_on (sv_Coro); 2971 sv_Coro = newSVpv ("Coro", 0); SvREADONLY_on (sv_Coro);
2968 cv_pool_handler = get_cv ("Coro::_pool_handler", 0); SvREADONLY_on (cv_pool_handler); 2972 cv_pool_handler = get_cv ("Coro::pool_handler", GV_ADD); SvREADONLY_on (cv_pool_handler);
2969 cv_coro_new = get_cv ("Coro::new", 0); SvREADONLY_on (cv_coro_new); 2973 cv_coro_state_new = get_cv ("Coro::State::new", 0); SvREADONLY_on (cv_coro_state_new);
2970 2974
2971 coro_stash = gv_stashpv ("Coro", TRUE); 2975 coro_stash = gv_stashpv ("Coro", TRUE);
2972 2976
2973 newCONSTSUB (coro_stash, "PRIO_MAX", newSViv (PRIO_MAX)); 2977 newCONSTSUB (coro_stash, "PRIO_MAX", newSViv (PRIO_MAX));
2974 newCONSTSUB (coro_stash, "PRIO_HIGH", newSViv (PRIO_HIGH)); 2978 newCONSTSUB (coro_stash, "PRIO_HIGH", newSViv (PRIO_HIGH));
3089 PUSHMARK (SP); 3093 PUSHMARK (SP);
3090 EXTEND (SP, 2); 3094 EXTEND (SP, 2);
3091 PUSHs (sv_Coro); 3095 PUSHs (sv_Coro);
3092 PUSHs ((SV *)cv_pool_handler); 3096 PUSHs ((SV *)cv_pool_handler);
3093 PUTBACK; 3097 PUTBACK;
3094 call_sv ((SV *)cv_coro_new, G_SCALAR); 3098 call_sv ((SV *)cv_coro_state_new, G_SCALAR);
3095 SPAGAIN; 3099 SPAGAIN;
3096 3100
3097 hv = (HV *)SvREFCNT_inc_NN (SvRV (POPs)); 3101 hv = (HV *)SvREFCNT_inc_NN (SvRV (POPs));
3098 } 3102 }
3099 3103

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines