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

98# define newSV(l) NEWSV(0,l) 98# define newSV(l) NEWSV(0,l)
99#endif 99#endif
100#ifndef CvISXSUB_on 100#ifndef CvISXSUB_on
101# define CvISXSUB_on(cv) (void)cv 101# define CvISXSUB_on(cv) (void)cv
102#endif 102#endif
103#ifndef CvISXSUB
104# define CvISXSUB(cv) (CvXSUB (cv) ? TRUE : FALSE)
105#endif
103 106
104/* 5.8.7 */ 107/* 5.8.7 */
105#ifndef SvRV_set 108#ifndef SvRV_set
106# define SvRV_set(s,v) SvRV(s) = (v) 109# define SvRV_set(s,v) SvRV(s) = (v)
107#endif 110#endif
180static SV *sv_pool_size; 183static SV *sv_pool_size;
181static SV *sv_async_pool_idle; 184static SV *sv_async_pool_idle;
182static AV *av_async_pool; 185static AV *av_async_pool;
183static SV *sv_Coro; 186static SV *sv_Coro;
184static CV *cv_pool_handler; 187static CV *cv_pool_handler;
185static CV *cv_coro_new; 188static CV *cv_coro_state_new;
186 189
187/* Coro::AnyEvent */ 190/* Coro::AnyEvent */
188static SV *sv_activity; 191static SV *sv_activity;
189 192
190static struct coro_cctx *cctx_first; 193static struct coro_cctx *cctx_first;
1609api_is_ready (pTHX_ SV *coro_sv) 1612api_is_ready (pTHX_ SV *coro_sv)
1610{ 1613{
1611 return !!(SvSTATE (coro_sv)->flags & CF_READY); 1614 return !!(SvSTATE (coro_sv)->flags & CF_READY);
1612} 1615}
1613 1616
1617/* expects to own a reference to next->hv */
1614INLINE 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
1615prepare_schedule (pTHX_ struct coro_transfer_args *ta) 1635prepare_schedule (pTHX_ struct coro_transfer_args *ta)
1616{ 1636{
1617 SV *prev_sv, *next_sv;
1618
1619 for (;;) 1637 for (;;)
1620 { 1638 {
1621 next_sv = coro_deq (aTHX); 1639 SV *next_sv = coro_deq (aTHX);
1622 1640
1623 /* nothing to schedule: call the idle handler */
1624 if (expect_false (!next_sv)) 1641 if (expect_false (!next_sv))
1625 { 1642 {
1643 /* nothing to schedule: call the idle handler */
1626 dSP; 1644 dSP;
1627 1645
1628 ENTER; 1646 ENTER;
1629 SAVETMPS; 1647 SAVETMPS;
1630 1648
1632 PUTBACK; 1650 PUTBACK;
1633 call_sv (get_sv ("Coro::idle", FALSE), G_VOID | G_DISCARD); 1651 call_sv (get_sv ("Coro::idle", FALSE), G_VOID | G_DISCARD);
1634 1652
1635 FREETMPS; 1653 FREETMPS;
1636 LEAVE; 1654 LEAVE;
1637 continue;
1638 } 1655 }
1639 1656 else
1640 ta->next = SvSTATE_hv (next_sv);
1641
1642 /* cannot transfer to destroyed coros, skip and look for next */
1643 if (expect_false (ta->next->flags & CF_DESTROYED))
1644 { 1657 {
1645 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))
1646 /* 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 */
1647 continue; 1663 else
1664 {
1665 next->flags &= ~CF_READY;
1666 --coro_nready;
1667
1668 return prepare_cede_to (aTHX_ ta, next);
1669 }
1648 } 1670 }
1649
1650 --coro_nready;
1651 break;
1652 } 1671 }
1653
1654 /* free this only after the transfer */
1655 prev_sv = SvRV (coro_current);
1656 ta->prev = SvSTATE_hv (prev_sv);
1657 TRANSFER_CHECK (*ta);
1658 assert (("FATAL: next coroutine isn't marked as ready in Coro (please report)", ta->next->flags & CF_READY));
1659 ta->next->flags &= ~CF_READY;
1660 SvRV_set (coro_current, next_sv);
1661
1662 free_coro_mortal (aTHX);
1663 coro_mortal = prev_sv;
1664} 1672}
1665 1673
1666INLINE void 1674INLINE void
1667prepare_cede (pTHX_ struct coro_transfer_args *ta) 1675prepare_cede (pTHX_ struct coro_transfer_args *ta)
1668{ 1676{
1760 1768
1761 if (!coro->invoke_cb) 1769 if (!coro->invoke_cb)
1762 return 1; /* loop till we have invoke */ 1770 return 1; /* loop till we have invoke */
1763 else 1771 else
1764 { 1772 {
1765 int i, len;
1766
1767 hv_store (hv, "desc", sizeof ("desc") - 1, 1773 hv_store (hv, "desc", sizeof ("desc") - 1,
1768 newSVpvn ("[async_pool]", sizeof ("[async_pool]") - 1), 0); 1774 newSVpvn ("[async_pool]", sizeof ("[async_pool]") - 1), 0);
1769 1775
1770 coro->saved_deffh = SvREFCNT_inc_NN ((SV *)PL_defoutgv); 1776 coro->saved_deffh = SvREFCNT_inc_NN ((SV *)PL_defoutgv);
1771
1772 len = av_len (coro->invoke_av);
1773 1777
1774 { 1778 {
1775 dSP; 1779 dSP;
1776 XPUSHs (sv_2mortal (coro->invoke_cb)); coro->invoke_cb = 0; 1780 XPUSHs (sv_2mortal (coro->invoke_cb)); coro->invoke_cb = 0;
1777 PUTBACK; 1781 PUTBACK;
1841 SV *data = (SV *)GENSUB_ARG; 1845 SV *data = (SV *)GENSUB_ARG;
1842 1846
1843 if (SvTYPE (SvRV (data)) != SVt_PVAV) 1847 if (SvTYPE (SvRV (data)) != SVt_PVAV)
1844 { 1848 {
1845 /* first call, set args */ 1849 /* first call, set args */
1846 int i;
1847 AV *av = newAV (); 1850 AV *av = newAV ();
1848 SV *coro = SvRV (data); 1851 SV *coro = SvRV (data);
1849 1852
1850 SvRV_set (data, (SV *)av); 1853 SvRV_set (data, (SV *)av);
1851 api_ready (aTHX_ coro); 1854 api_ready (aTHX_ coro);
2959 2962
2960 av_async_pool = coro_get_av (aTHX_ "Coro::async_pool", TRUE); 2963 av_async_pool = coro_get_av (aTHX_ "Coro::async_pool", TRUE);
2961 sv_pool_rss = coro_get_sv (aTHX_ "Coro::POOL_RSS" , TRUE); 2964 sv_pool_rss = coro_get_sv (aTHX_ "Coro::POOL_RSS" , TRUE);
2962 sv_pool_size = coro_get_sv (aTHX_ "Coro::POOL_SIZE" , TRUE); 2965 sv_pool_size = coro_get_sv (aTHX_ "Coro::POOL_SIZE" , TRUE);
2963 cv_coro_run = get_cv ( "Coro::_terminate", GV_ADD); 2966 cv_coro_run = get_cv ( "Coro::_terminate", GV_ADD);
2964 cv_coro_terminate = get_cv ( "Coro::terminate", GV_ADD); 2967 cv_coro_terminate = get_cv ( "Coro::terminate" , GV_ADD);
2965 coro_current = coro_get_sv (aTHX_ "Coro::current" , FALSE); 2968 coro_current = coro_get_sv (aTHX_ "Coro::current" , FALSE); SvREADONLY_on (coro_current);
2966 SvREADONLY_on (coro_current);
2967 2969
2968 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);
2969 sv_Coro = newSVpv ("Coro", 0); SvREADONLY_on (sv_Coro); 2971 sv_Coro = newSVpv ("Coro", 0); SvREADONLY_on (sv_Coro);
2970 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);
2971 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);
2972 2974
2973 coro_stash = gv_stashpv ("Coro", TRUE); 2975 coro_stash = gv_stashpv ("Coro", TRUE);
2974 2976
2975 newCONSTSUB (coro_stash, "PRIO_MAX", newSViv (PRIO_MAX)); 2977 newCONSTSUB (coro_stash, "PRIO_MAX", newSViv (PRIO_MAX));
2976 newCONSTSUB (coro_stash, "PRIO_HIGH", newSViv (PRIO_HIGH)); 2978 newCONSTSUB (coro_stash, "PRIO_HIGH", newSViv (PRIO_HIGH));
3091 PUSHMARK (SP); 3093 PUSHMARK (SP);
3092 EXTEND (SP, 2); 3094 EXTEND (SP, 2);
3093 PUSHs (sv_Coro); 3095 PUSHs (sv_Coro);
3094 PUSHs ((SV *)cv_pool_handler); 3096 PUSHs ((SV *)cv_pool_handler);
3095 PUTBACK; 3097 PUTBACK;
3096 call_sv (cv_coro_new, G_SCALAR); 3098 call_sv ((SV *)cv_coro_state_new, G_SCALAR);
3097 SPAGAIN; 3099 SPAGAIN;
3098 3100
3099 hv = (HV *)SvREFCNT_inc_NN (SvRV (POPs)); 3101 hv = (HV *)SvREFCNT_inc_NN (SvRV (POPs));
3100 } 3102 }
3101 3103
3106 assert (!coro->invoke_av); 3108 assert (!coro->invoke_av);
3107 coro->invoke_cb = SvREFCNT_inc (cb); 3109 coro->invoke_cb = SvREFCNT_inc (cb);
3108 coro->invoke_av = av; 3110 coro->invoke_av = av;
3109 } 3111 }
3110 3112
3111 api_ready ((SV *)hv); 3113 api_ready (aTHX_ (SV *)hv);
3112 3114
3113 if (GIMME_V != G_VOID) 3115 if (GIMME_V != G_VOID)
3114 XPUSHs (sv_2mortal (newRV_noinc ((SV *)hv))); 3116 XPUSHs (sv_2mortal (newRV_noinc ((SV *)hv)));
3115 else 3117 else
3116 SvREFCNT_dec (hv); 3118 SvREFCNT_dec (hv);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines