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.321 by root, Sat Nov 22 02:09:54 2008 UTC

1#define CORO_CLONE 1 //D
2
1#include "libcoro/coro.c" 3#include "libcoro/coro.c"
2 4
3#define PERL_NO_GET_CONTEXT 5#define PERL_NO_GET_CONTEXT
4#define PERL_EXT 6#define PERL_EXT
5 7
101# define CvISXSUB_on(cv) (void)cv 103# define CvISXSUB_on(cv) (void)cv
102#endif 104#endif
103#ifndef CvISXSUB 105#ifndef CvISXSUB
104# define CvISXSUB(cv) (CvXSUB (cv) ? TRUE : FALSE) 106# define CvISXSUB(cv) (CvXSUB (cv) ? TRUE : FALSE)
105#endif 107#endif
108#ifndef Newx
109# define Newx(ptr,nitems,type) New (0,ptr,nitems,type)
110#endif
106 111
107/* 5.8.7 */ 112/* 5.8.7 */
108#ifndef SvRV_set 113#ifndef SvRV_set
109# define SvRV_set(s,v) SvRV(s) = (v) 114# define SvRV_set(s,v) SvRV(s) = (v)
110#endif 115#endif
170static AV *main_mainstack; /* used to differentiate between $main and others */ 175static AV *main_mainstack; /* used to differentiate between $main and others */
171static JMPENV *main_top_env; 176static JMPENV *main_top_env;
172static HV *coro_state_stash, *coro_stash; 177static HV *coro_state_stash, *coro_stash;
173static volatile SV *coro_mortal; /* will be freed/thrown after next transfer */ 178static volatile SV *coro_mortal; /* will be freed/thrown after next transfer */
174 179
180static AV *av_destroy; /* destruction queue */
181static SV *sv_manager; /* the manager coro */
182
175static GV *irsgv; /* $/ */ 183static GV *irsgv; /* $/ */
176static GV *stdoutgv; /* *STDOUT */ 184static GV *stdoutgv; /* *STDOUT */
177static SV *rv_diehook; 185static SV *rv_diehook;
178static SV *rv_warnhook; 186static SV *rv_warnhook;
179static HV *hv_sig; /* %SIG */ 187static HV *hv_sig; /* %SIG */
180 188
181/* async_pool helper stuff */ 189/* async_pool helper stuff */
182static SV *sv_pool_rss; 190static SV *sv_pool_rss;
183static SV *sv_pool_size; 191static SV *sv_pool_size;
184static SV *sv_async_pool_idle; 192static SV *sv_async_pool_idle; /* description string */
185static AV *av_async_pool; 193static AV *av_async_pool; /* idle pool */
186static SV *sv_Coro; 194static SV *sv_Coro; /* class string */
187static CV *cv_pool_handler; 195static CV *cv_pool_handler;
188static CV *cv_coro_new; 196static CV *cv_coro_state_new;
189 197
190/* Coro::AnyEvent */ 198/* Coro::AnyEvent */
191static SV *sv_activity; 199static SV *sv_activity;
192 200
193static struct coro_cctx *cctx_first; 201static struct coro_cctx *cctx_first;
344 GV *gvp; 352 GV *gvp;
345 return sv_2cv (sv, &st, &gvp, 0); 353 return sv_2cv (sv, &st, &gvp, 0);
346} 354}
347 355
348static AV * 356static AV *
349coro_clone_padlist (pTHX_ CV *cv) 357coro_derive_padlist (pTHX_ CV *cv)
350{ 358{
351 AV *padlist = CvPADLIST (cv); 359 AV *padlist = CvPADLIST (cv);
352 AV *newpadlist, *newpad; 360 AV *newpadlist, *newpad;
353 361
354 newpadlist = newAV (); 362 newpadlist = newAV ();
474 CV *cp = Perl_cv_clone (aTHX_ cv); 482 CV *cp = Perl_cv_clone (aTHX_ cv);
475 CvPADLIST (cv) = CvPADLIST (cp); 483 CvPADLIST (cv) = CvPADLIST (cp);
476 CvPADLIST (cp) = 0; 484 CvPADLIST (cp) = 0;
477 SvREFCNT_dec (cp); 485 SvREFCNT_dec (cp);
478#else 486#else
479 CvPADLIST (cv) = coro_clone_padlist (aTHX_ cv); 487 CvPADLIST (cv) = coro_derive_padlist (aTHX_ cv);
480#endif 488#endif
481 } 489 }
482} 490}
483 491
484static void 492static void
834slf_check_nop (pTHX_ struct CoroSLF *frame) 842slf_check_nop (pTHX_ struct CoroSLF *frame)
835{ 843{
836 return 0; 844 return 0;
837} 845}
838 846
847static int
848slf_check_repeat (pTHX_ struct CoroSLF *frame)
849{
850 return 1;
851}
852
839static UNOP coro_setup_op; 853static UNOP coro_setup_op;
840 854
841static void NOINLINE /* noinline to keep it out of the transfer fast path */ 855static void NOINLINE /* noinline to keep it out of the transfer fast path */
842coro_setup (pTHX_ struct coro *coro) 856coro_setup (pTHX_ struct coro *coro)
843{ 857{
892 slf_frame.prepare = prepare_nop; /* provide a nop function for an eventual pp_slf */ 906 slf_frame.prepare = prepare_nop; /* provide a nop function for an eventual pp_slf */
893 slf_frame.check = slf_check_nop; /* signal pp_slf to not repeat */ 907 slf_frame.check = slf_check_nop; /* signal pp_slf to not repeat */
894 908
895 /* and we have to provide the pp_slf op in any case, so pp_slf can skip it */ 909 /* and we have to provide the pp_slf op in any case, so pp_slf can skip it */
896 coro_setup_op.op_next = PL_op; 910 coro_setup_op.op_next = PL_op;
897 coro_setup_op.op_type = OP_CUSTOM; 911 coro_setup_op.op_type = OP_ENTERSUB;
898 coro_setup_op.op_ppaddr = pp_slf; 912 coro_setup_op.op_ppaddr = pp_slf;
899 /* no flags etc. required, as an init function won't be called */ 913 /* no flags etc. required, as an init function won't be called */
900 914
901 PL_op = (OP *)&coro_setup_op; 915 PL_op = (OP *)&coro_setup_op;
902 916
1017 { 1031 {
1018 PERL_CONTEXT *cx = &cxstack[cxstack_ix]; 1032 PERL_CONTEXT *cx = &cxstack[cxstack_ix];
1019 1033
1020 if (CxTYPE (cx) == CXt_SUB && oldcxix < cxstack_ix) 1034 if (CxTYPE (cx) == CXt_SUB && oldcxix < cxstack_ix)
1021 { 1035 {
1022 runops_proc_t old_runops = PL_runops;
1023 dSP; 1036 dSP;
1024 GV *gv = CvGV (cx->blk_sub.cv); 1037 GV *gv = CvGV (cx->blk_sub.cv);
1025 SV *fullname = sv_2mortal (newSV (0)); 1038 SV *fullname = sv_2mortal (newSV (0));
1026 1039
1027 if (isGV (gv)) 1040 if (isGV (gv))
1612api_is_ready (pTHX_ SV *coro_sv) 1625api_is_ready (pTHX_ SV *coro_sv)
1613{ 1626{
1614 return !!(SvSTATE (coro_sv)->flags & CF_READY); 1627 return !!(SvSTATE (coro_sv)->flags & CF_READY);
1615} 1628}
1616 1629
1630/* expects to own a reference to next->hv */
1617INLINE void 1631INLINE void
1632prepare_schedule_to (pTHX_ struct coro_transfer_args *ta, struct coro *next)
1633{
1634 SV *prev_sv = SvRV (coro_current);
1635
1636 ta->prev = SvSTATE_hv (prev_sv);
1637 ta->next = next;
1638
1639 TRANSFER_CHECK (*ta);
1640
1641 SvRV_set (coro_current, (SV *)next->hv);
1642
1643 free_coro_mortal (aTHX);
1644 coro_mortal = prev_sv;
1645}
1646
1647static void
1618prepare_schedule (pTHX_ struct coro_transfer_args *ta) 1648prepare_schedule (pTHX_ struct coro_transfer_args *ta)
1619{ 1649{
1620 SV *prev_sv, *next_sv;
1621
1622 for (;;) 1650 for (;;)
1623 { 1651 {
1624 next_sv = coro_deq (aTHX); 1652 SV *next_sv = coro_deq (aTHX);
1625 1653
1626 /* nothing to schedule: call the idle handler */
1627 if (expect_false (!next_sv)) 1654 if (expect_true (next_sv))
1628 { 1655 {
1656 struct coro *next = SvSTATE_hv (next_sv);
1657
1658 /* cannot transfer to destroyed coros, skip and look for next */
1659 if (expect_false (next->flags & CF_DESTROYED))
1660 SvREFCNT_dec (next_sv); /* coro_nready has already been taken care of by destroy */
1661 else
1662 {
1663 next->flags &= ~CF_READY;
1664 --coro_nready;
1665
1666 prepare_schedule_to (aTHX_ ta, next);
1667 break;
1668 }
1669 }
1670 else
1671 {
1672 /* nothing to schedule: call the idle handler */
1629 dSP; 1673 dSP;
1630 1674
1631 ENTER; 1675 ENTER;
1632 SAVETMPS; 1676 SAVETMPS;
1633 1677
1635 PUTBACK; 1679 PUTBACK;
1636 call_sv (get_sv ("Coro::idle", FALSE), G_VOID | G_DISCARD); 1680 call_sv (get_sv ("Coro::idle", FALSE), G_VOID | G_DISCARD);
1637 1681
1638 FREETMPS; 1682 FREETMPS;
1639 LEAVE; 1683 LEAVE;
1640 continue;
1641 } 1684 }
1642
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 {
1648 SvREFCNT_dec (next_sv);
1649 /* coro_nready has already been taken care of by destroy */
1650 continue;
1651 }
1652
1653 --coro_nready;
1654 break;
1655 } 1685 }
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} 1686}
1668 1687
1669INLINE void 1688INLINE void
1670prepare_cede (pTHX_ struct coro_transfer_args *ta) 1689prepare_cede (pTHX_ struct coro_transfer_args *ta)
1671{ 1690{
1692{ 1711{
1693 struct coro_transfer_args ta; 1712 struct coro_transfer_args ta;
1694 1713
1695 prepare_schedule (aTHX_ &ta); 1714 prepare_schedule (aTHX_ &ta);
1696 TRANSFER (ta, 1); 1715 TRANSFER (ta, 1);
1716}
1717
1718static void
1719api_schedule_to (pTHX_ SV *coro_sv)
1720{
1721 struct coro_transfer_args ta;
1722 struct coro *next = SvSTATE (coro_sv);
1723
1724 SvREFCNT_inc_NN (coro_sv);
1725 prepare_schedule_to (aTHX_ &ta, next);
1697} 1726}
1698 1727
1699static int 1728static int
1700api_cede (pTHX) 1729api_cede (pTHX)
1701{ 1730{
1748 if (coro->flags & CF_RUNNING) 1777 if (coro->flags & CF_RUNNING)
1749 PL_runops = RUNOPS_DEFAULT; 1778 PL_runops = RUNOPS_DEFAULT;
1750 else 1779 else
1751 coro->slot->runops = RUNOPS_DEFAULT; 1780 coro->slot->runops = RUNOPS_DEFAULT;
1752 } 1781 }
1782}
1783
1784static void
1785coro_call_on_destroy (pTHX_ struct coro *coro)
1786{
1787 SV **on_destroyp = hv_fetch (coro->hv, "_on_destroy", sizeof ("_on_destroy") - 1, 0);
1788 SV **statusp = hv_fetch (coro->hv, "_status", sizeof ("_status") - 1, 0);
1789
1790 if (on_destroyp)
1791 {
1792 AV *on_destroy = (AV *)SvRV (*on_destroyp);
1793
1794 while (AvFILLp (on_destroy) >= 0)
1795 {
1796 dSP; /* don't disturb outer sp */
1797 SV *cb = av_pop (on_destroy);
1798
1799 PUSHMARK (SP);
1800
1801 if (statusp)
1802 {
1803 int i;
1804 AV *status = (AV *)SvRV (*statusp);
1805 EXTEND (SP, AvFILLp (status) + 1);
1806
1807 for (i = 0; i <= AvFILLp (status); ++i)
1808 PUSHs (AvARRAY (status)[i]);
1809 }
1810
1811 PUTBACK;
1812 call_sv (sv_2mortal (cb), G_VOID | G_DISCARD);
1813 }
1814 }
1815}
1816
1817static void
1818slf_init_terminate (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items)
1819{
1820 int i;
1821 HV *hv = (HV *)SvRV (coro_current);
1822 AV *av = newAV ();
1823
1824 av_extend (av, items - 1);
1825 for (i = 0; i < items; ++i)
1826 av_push (av, SvREFCNT_inc_NN (arg [i]));
1827
1828 hv_store (hv, "_status", sizeof ("_status") - 1, newRV_noinc ((SV *)av), 0);
1829
1830 av_push (av_destroy, (SV *)newRV_inc ((SV *)hv)); /* RVinc for perl */
1831 api_ready (aTHX_ sv_manager);
1832
1833 frame->prepare = prepare_schedule;
1834 frame->check = slf_check_repeat;
1753} 1835}
1754 1836
1755/*****************************************************************************/ 1837/*****************************************************************************/
1756/* async pool handler */ 1838/* async pool handler */
1757 1839
1990static void 2072static void
1991slf_init_schedule (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items) 2073slf_init_schedule (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items)
1992{ 2074{
1993 frame->prepare = prepare_schedule; 2075 frame->prepare = prepare_schedule;
1994 frame->check = slf_check_nop; 2076 frame->check = slf_check_nop;
2077}
2078
2079static void
2080slf_prepare_schedule_to (pTHX_ struct coro_transfer_args *ta)
2081{
2082 struct coro *next = (struct coro *)slf_frame.data;
2083
2084 SvREFCNT_inc_NN (next->hv);
2085 prepare_schedule_to (aTHX_ ta, next);
2086}
2087
2088static void
2089slf_init_schedule_to (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items)
2090{
2091 if (!items)
2092 croak ("Coro::schedule_to expects a coroutine argument, caught");
2093
2094 frame->data = (void *)SvSTATE (arg [0]);
2095 frame->prepare = slf_prepare_schedule_to;
2096 frame->check = slf_check_nop;
2097}
2098
2099static void
2100slf_init_cede_to (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items)
2101{
2102 api_ready (aTHX_ SvRV (coro_current));
2103
2104 slf_init_schedule_to (aTHX_ frame, cv, arg, items);
1995} 2105}
1996 2106
1997static void 2107static void
1998slf_init_cede (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items) 2108slf_init_cede (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items)
1999{ 2109{
2145 } 2255 }
2146 else 2256 else
2147 slf_argc = 0; 2257 slf_argc = 0;
2148 2258
2149 PL_op->op_ppaddr = pp_slf; 2259 PL_op->op_ppaddr = pp_slf;
2150 PL_op->op_type = OP_CUSTOM; /* maybe we should leave it at entersub? */ 2260 /*PL_op->op_type = OP_CUSTOM; /* we do behave like entersub still */
2151 2261
2152 PL_op = (OP *)&slf_restore; 2262 PL_op = (OP *)&slf_restore;
2153} 2263}
2154 2264
2155/*****************************************************************************/ 2265/*****************************************************************************/
2619 XSRETURN_EMPTY; 2729 XSRETURN_EMPTY;
2620} 2730}
2621 2731
2622/*****************************************************************************/ 2732/*****************************************************************************/
2623 2733
2734#if CORO_CLONE
2735# include "clone.c"
2736#endif
2737
2624MODULE = Coro::State PACKAGE = Coro::State PREFIX = api_ 2738MODULE = Coro::State PACKAGE = Coro::State PREFIX = api_
2625 2739
2626PROTOTYPES: DISABLE 2740PROTOTYPES: DISABLE
2627 2741
2628BOOT: 2742BOOT:
2660 2774
2661 { 2775 {
2662 SV *slf = sv_2mortal (newSViv (PTR2IV (pp_slf))); 2776 SV *slf = sv_2mortal (newSViv (PTR2IV (pp_slf)));
2663 2777
2664 if (!PL_custom_op_names) PL_custom_op_names = newHV (); 2778 if (!PL_custom_op_names) PL_custom_op_names = newHV ();
2665 hv_store_ent (PL_custom_op_names, slf, 2779 hv_store_ent (PL_custom_op_names, slf, newSVpv ("coro_slf", 0), 0);
2666 newSVpv ("coro_slf", 0), 0);
2667 2780
2668 if (!PL_custom_op_descs) PL_custom_op_descs = newHV (); 2781 if (!PL_custom_op_descs) PL_custom_op_descs = newHV ();
2669 hv_store_ent (PL_custom_op_descs, slf, 2782 hv_store_ent (PL_custom_op_descs, slf, newSVpv ("coro schedule like function", 0), 0);
2670 newSVpv ("coro schedule like function", 0), 0);
2671 } 2783 }
2672 2784
2673 coroapi.ver = CORO_API_VERSION; 2785 coroapi.ver = CORO_API_VERSION;
2674 coroapi.rev = CORO_API_REVISION; 2786 coroapi.rev = CORO_API_REVISION;
2675 2787
2768void 2880void
2769_exit (int code) 2881_exit (int code)
2770 PROTOTYPE: $ 2882 PROTOTYPE: $
2771 CODE: 2883 CODE:
2772 _exit (code); 2884 _exit (code);
2885
2886#if CORO_CLONE
2887
2888SV *
2889clone (Coro::State coro)
2890 CODE:
2891{
2892 struct coro *ncoro = coro_clone (coro);
2893 MAGIC *mg;
2894 /* TODO: too much duplication */
2895 ncoro->hv = newHV ();
2896 mg = sv_magicext ((SV *)ncoro->hv, 0, CORO_MAGIC_type_state, &coro_state_vtbl, (char *)ncoro, 0);
2897 mg->mg_flags |= MGf_DUP;
2898 RETVAL = sv_bless (newRV_noinc ((SV *)ncoro->hv), SvSTASH (coro->hv));
2899}
2900 OUTPUT:
2901 RETVAL
2902
2903#endif
2773 2904
2774int 2905int
2775cctx_stacksize (int new_stacksize = 0) 2906cctx_stacksize (int new_stacksize = 0)
2776 PROTOTYPE: ;$ 2907 PROTOTYPE: ;$
2777 CODE: 2908 CODE:
2953 3084
2954BOOT: 3085BOOT:
2955{ 3086{
2956 int i; 3087 int i;
2957 3088
2958 av_async_pool = coro_get_av (aTHX_ "Coro::async_pool", TRUE);
2959 sv_pool_rss = coro_get_sv (aTHX_ "Coro::POOL_RSS" , TRUE); 3089 sv_pool_rss = coro_get_sv (aTHX_ "Coro::POOL_RSS" , TRUE);
2960 sv_pool_size = coro_get_sv (aTHX_ "Coro::POOL_SIZE" , TRUE); 3090 sv_pool_size = coro_get_sv (aTHX_ "Coro::POOL_SIZE" , TRUE);
2961 cv_coro_run = get_cv ( "Coro::_terminate", GV_ADD); 3091 cv_coro_run = get_cv ( "Coro::_terminate", GV_ADD);
2962 cv_coro_terminate = get_cv ( "Coro::terminate", GV_ADD); 3092 cv_coro_terminate = get_cv ( "Coro::terminate" , GV_ADD);
2963 coro_current = coro_get_sv (aTHX_ "Coro::current" , FALSE); 3093 coro_current = coro_get_sv (aTHX_ "Coro::current" , FALSE); SvREADONLY_on (coro_current);
2964 SvREADONLY_on (coro_current); 3094 av_async_pool = coro_get_av (aTHX_ "Coro::async_pool", TRUE);
3095 av_destroy = coro_get_av (aTHX_ "Coro::destroy" , TRUE);
3096 sv_manager = coro_get_sv (aTHX_ "Coro::manager" , TRUE);
2965 3097
2966 sv_async_pool_idle = newSVpv ("[async pool idle]", 0); SvREADONLY_on (sv_async_pool_idle); 3098 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); 3099 sv_Coro = newSVpv ("Coro", 0); SvREADONLY_on (sv_Coro);
2968 cv_pool_handler = get_cv ("Coro::_pool_handler", 0); SvREADONLY_on (cv_pool_handler); 3100 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); 3101 cv_coro_state_new = get_cv ("Coro::State::new", 0); SvREADONLY_on (cv_coro_state_new);
2970 3102
2971 coro_stash = gv_stashpv ("Coro", TRUE); 3103 coro_stash = gv_stashpv ("Coro", TRUE);
2972 3104
2973 newCONSTSUB (coro_stash, "PRIO_MAX", newSViv (PRIO_MAX)); 3105 newCONSTSUB (coro_stash, "PRIO_MAX", newSViv (PRIO_MAX));
2974 newCONSTSUB (coro_stash, "PRIO_HIGH", newSViv (PRIO_HIGH)); 3106 newCONSTSUB (coro_stash, "PRIO_HIGH", newSViv (PRIO_HIGH));
2982 3114
2983 { 3115 {
2984 SV *sv = coro_get_sv (aTHX_ "Coro::API", TRUE); 3116 SV *sv = coro_get_sv (aTHX_ "Coro::API", TRUE);
2985 3117
2986 coroapi.schedule = api_schedule; 3118 coroapi.schedule = api_schedule;
3119 coroapi.schedule_to = api_schedule_to;
2987 coroapi.cede = api_cede; 3120 coroapi.cede = api_cede;
2988 coroapi.cede_notself = api_cede_notself; 3121 coroapi.cede_notself = api_cede_notself;
2989 coroapi.ready = api_ready; 3122 coroapi.ready = api_ready;
2990 coroapi.is_ready = api_is_ready; 3123 coroapi.is_ready = api_is_ready;
2991 coroapi.nready = coro_nready; 3124 coroapi.nready = coro_nready;
2996 SvREADONLY_on (sv); 3129 SvREADONLY_on (sv);
2997 } 3130 }
2998} 3131}
2999 3132
3000void 3133void
3134terminate (...)
3135 CODE:
3136 CORO_EXECUTE_SLF_XS (slf_init_terminate);
3137
3138void
3001schedule (...) 3139schedule (...)
3002 CODE: 3140 CODE:
3003 CORO_EXECUTE_SLF_XS (slf_init_schedule); 3141 CORO_EXECUTE_SLF_XS (slf_init_schedule);
3142
3143void
3144schedule_to (...)
3145 CODE:
3146 CORO_EXECUTE_SLF_XS (slf_init_schedule_to);
3147
3148void
3149cede_to (...)
3150 CODE:
3151 CORO_EXECUTE_SLF_XS (slf_init_cede_to);
3004 3152
3005void 3153void
3006cede (...) 3154cede (...)
3007 CODE: 3155 CODE:
3008 CORO_EXECUTE_SLF_XS (slf_init_cede); 3156 CORO_EXECUTE_SLF_XS (slf_init_cede);
3009 3157
3010void 3158void
3011cede_notself (...) 3159cede_notself (...)
3012 CODE: 3160 CODE:
3013 CORO_EXECUTE_SLF_XS (slf_init_cede_notself); 3161 CORO_EXECUTE_SLF_XS (slf_init_cede_notself);
3162
3163void
3164_cancel (Coro::State self)
3165 CODE:
3166 coro_state_destroy (aTHX_ self);
3167 coro_call_on_destroy (aTHX_ self);
3014 3168
3015void 3169void
3016_set_current (SV *current) 3170_set_current (SV *current)
3017 PROTOTYPE: $ 3171 PROTOTYPE: $
3018 CODE: 3172 CODE:
3089 PUSHMARK (SP); 3243 PUSHMARK (SP);
3090 EXTEND (SP, 2); 3244 EXTEND (SP, 2);
3091 PUSHs (sv_Coro); 3245 PUSHs (sv_Coro);
3092 PUSHs ((SV *)cv_pool_handler); 3246 PUSHs ((SV *)cv_pool_handler);
3093 PUTBACK; 3247 PUTBACK;
3094 call_sv ((SV *)cv_coro_new, G_SCALAR); 3248 call_sv ((SV *)cv_coro_state_new, G_SCALAR);
3095 SPAGAIN; 3249 SPAGAIN;
3096 3250
3097 hv = (HV *)SvREFCNT_inc_NN (SvRV (POPs)); 3251 hv = (HV *)SvREFCNT_inc_NN (SvRV (POPs));
3098 } 3252 }
3099 3253

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines