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.315 by root, Thu Nov 20 05:25:17 2008 UTC vs.
Revision 1.316 by root, Thu Nov 20 06:01:40 2008 UTC

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{

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines