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.282 by root, Sun Nov 16 10:33:08 2008 UTC vs.
Revision 1.286 by root, Mon Nov 17 04:19:49 2008 UTC

166static struct CoroAPI coroapi; 166static struct CoroAPI coroapi;
167static AV *main_mainstack; /* used to differentiate between $main and others */ 167static AV *main_mainstack; /* used to differentiate between $main and others */
168static JMPENV *main_top_env; 168static JMPENV *main_top_env;
169static HV *coro_state_stash, *coro_stash; 169static HV *coro_state_stash, *coro_stash;
170static volatile SV *coro_mortal; /* will be freed/thrown after next transfer */ 170static volatile SV *coro_mortal; /* will be freed/thrown after next transfer */
171static volatile struct coro *transfer_next;
172 171
173static GV *irsgv; /* $/ */ 172static GV *irsgv; /* $/ */
174static GV *stdoutgv; /* *STDOUT */ 173static GV *stdoutgv; /* *STDOUT */
175static SV *rv_diehook; 174static SV *rv_diehook;
176static SV *rv_warnhook; 175static SV *rv_warnhook;
242/* this is a structure representing a perl-level coroutine */ 241/* this is a structure representing a perl-level coroutine */
243struct coro { 242struct coro {
244 /* the C coroutine allocated to this perl coroutine, if any */ 243 /* the C coroutine allocated to this perl coroutine, if any */
245 coro_cctx *cctx; 244 coro_cctx *cctx;
246 245
247 /* process data */ 246 /* state data */
248 struct CoroSLF slf_frame; /* saved slf frame */ 247 struct CoroSLF slf_frame; /* saved slf frame */
249 AV *mainstack; 248 AV *mainstack;
250 perl_slots *slot; /* basically the saved sp */ 249 perl_slots *slot; /* basically the saved sp */
251 250
252 AV *args; /* data associated with this coroutine (initial args) */ 251 AV *args; /* data associated with this coroutine (initial args) */
270}; 269};
271 270
272typedef struct coro *Coro__State; 271typedef struct coro *Coro__State;
273typedef struct coro *Coro__State_or_hashref; 272typedef struct coro *Coro__State_or_hashref;
274 273
274/* the following variables are effectively part of the perl context */
275/* and get copied between struct coro and these variables */
276/* the mainr easonw e don't support windows process emulation */
275static struct CoroSLF slf_frame; /* the current slf frame */ 277static struct CoroSLF slf_frame; /* the current slf frame */
278static SV *coro_throw;
276 279
277/** Coro ********************************************************************/ 280/** Coro ********************************************************************/
278 281
279#define PRIO_MAX 3 282#define PRIO_MAX 3
280#define PRIO_HIGH 1 283#define PRIO_HIGH 1
514 } 517 }
515 518
516 PUTBACK; 519 PUTBACK;
517 } 520 }
518 521
519 slf_frame = c->slf_frame; 522 slf_frame = c->slf_frame;
523 coro_throw = c->throw;
520} 524}
521 525
522static void 526static void
523save_perl (pTHX_ Coro__State c) 527save_perl (pTHX_ Coro__State c)
524{ 528{
529 c->throw = coro_throw;
525 c->slf_frame = slf_frame; 530 c->slf_frame = slf_frame;
526 531
527 { 532 {
528 dSP; 533 dSP;
529 I32 cxix = cxstack_ix; 534 I32 cxix = cxstack_ix;
822slf_check_nop (pTHX_ struct CoroSLF *frame) 827slf_check_nop (pTHX_ struct CoroSLF *frame)
823{ 828{
824 return 0; 829 return 0;
825} 830}
826 831
827static void 832static void NOINLINE /* noinline to keep it out of the transfer fast path */
828coro_setup (pTHX_ struct coro *coro) 833coro_setup (pTHX_ struct coro *coro)
829{ 834{
830 /* 835 /*
831 * emulate part of the perl startup here. 836 * emulate part of the perl startup here.
832 */ 837 */
875 /* this newly created coroutine might be run on an existing cctx which most 880 /* this newly created coroutine might be run on an existing cctx which most
876 * likely was suspended in pp_slf, so we have to emulate entering pp_slf here. 881 * likely was suspended in pp_slf, so we have to emulate entering pp_slf here.
877 */ 882 */
878 slf_frame.prepare = prepare_nop; /* provide a nop function for an eventual pp_slf */ 883 slf_frame.prepare = prepare_nop; /* provide a nop function for an eventual pp_slf */
879 slf_frame.check = slf_check_nop; /* signal pp_slf to not repeat */ 884 slf_frame.check = slf_check_nop; /* signal pp_slf to not repeat */
885
886 coro_throw = coro->throw;
880} 887}
881 888
882static void 889static void
883coro_destruct (pTHX_ struct coro *coro) 890coro_destruct (pTHX_ struct coro *coro)
884{ 891{
908 915
909 SvREFCNT_dec (PL_diehook); 916 SvREFCNT_dec (PL_diehook);
910 SvREFCNT_dec (PL_warnhook); 917 SvREFCNT_dec (PL_warnhook);
911 918
912 SvREFCNT_dec (coro->saved_deffh); 919 SvREFCNT_dec (coro->saved_deffh);
913 SvREFCNT_dec (coro->throw); 920 SvREFCNT_dec (coro_throw);
914 921
915 coro_destruct_stacks (aTHX); 922 coro_destruct_stacks (aTHX);
916} 923}
917 924
918INLINE void 925INLINE void
1087 1094
1088/* the tail of transfer: execute stuff we can only do after a transfer */ 1095/* the tail of transfer: execute stuff we can only do after a transfer */
1089INLINE void 1096INLINE void
1090transfer_tail (pTHX) 1097transfer_tail (pTHX)
1091{ 1098{
1092 struct coro *next = (struct coro *)transfer_next;
1093 assert (!(transfer_next = 0)); /* just used for the side effect when asserts are enabled */
1094 assert (("FATAL: next coroutine was zero in transfer_tail (please report)", next));
1095
1096 free_coro_mortal (aTHX); 1099 free_coro_mortal (aTHX);
1097
1098 if (expect_false (next->throw))
1099 {
1100 SV *exception = sv_2mortal (next->throw);
1101
1102 next->throw = 0;
1103 sv_setsv (ERRSV, exception);
1104 croak (0);
1105 }
1106} 1100}
1107 1101
1108/* 1102/*
1109 * this is a _very_ stripped down perl interpreter ;) 1103 * this is a _very_ stripped down perl interpreter ;)
1110 */ 1104 */
1125 1119
1126 /* inject a fake subroutine call to cctx_init */ 1120 /* inject a fake subroutine call to cctx_init */
1127 cctx_prepare (aTHX_ (coro_cctx *)arg); 1121 cctx_prepare (aTHX_ (coro_cctx *)arg);
1128 1122
1129 /* cctx_run is the alternative tail of transfer() */ 1123 /* cctx_run is the alternative tail of transfer() */
1130 /* TODO: throwing an exception here might be deadly, VERIFY */
1131 transfer_tail (aTHX); 1124 transfer_tail (aTHX);
1132 1125
1133 /* somebody or something will hit me for both perl_run and PL_restartop */ 1126 /* somebody or something will hit me for both perl_run and PL_restartop */
1134 PL_restartop = PL_op; 1127 PL_restartop = PL_op;
1135 perl_run (PL_curinterp); 1128 perl_run (PL_curinterp);
1291/** coroutine switching *****************************************************/ 1284/** coroutine switching *****************************************************/
1292 1285
1293static void 1286static void
1294transfer_check (pTHX_ struct coro *prev, struct coro *next) 1287transfer_check (pTHX_ struct coro *prev, struct coro *next)
1295{ 1288{
1289 /* TODO: throwing up here is considered harmful */
1290
1296 if (expect_true (prev != next)) 1291 if (expect_true (prev != next))
1297 { 1292 {
1298 if (expect_false (!(prev->flags & (CF_RUNNING | CF_NEW)))) 1293 if (expect_false (!(prev->flags & (CF_RUNNING | CF_NEW))))
1299 croak ("Coro::State::transfer called with non-running/new prev Coro::State, but can only transfer from running or new states,"); 1294 croak ("Coro::State::transfer called with non-running/new prev Coro::State, but can only transfer from running or new states,");
1300 1295
1310#endif 1305#endif
1311 } 1306 }
1312} 1307}
1313 1308
1314/* always use the TRANSFER macro */ 1309/* always use the TRANSFER macro */
1315static void NOINLINE 1310static void NOINLINE /* noinline so we have a fixed stackframe */
1316transfer (pTHX_ struct coro *prev, struct coro *next, int force_cctx) 1311transfer (pTHX_ struct coro *prev, struct coro *next, int force_cctx)
1317{ 1312{
1318 dSTACKLEVEL; 1313 dSTACKLEVEL;
1319 1314
1320 /* sometimes transfer is only called to set idle_sp */ 1315 /* sometimes transfer is only called to set idle_sp */
1376 1371
1377 ++next->usecount; 1372 ++next->usecount;
1378 1373
1379 if (expect_true (!next->cctx)) 1374 if (expect_true (!next->cctx))
1380 next->cctx = cctx_get (aTHX); 1375 next->cctx = cctx_get (aTHX);
1381
1382 assert (("FATAL: transfer_next already nonzero in Coro (please report)", !transfer_next));
1383 transfer_next = next;
1384 1376
1385 if (expect_false (prev__cctx != next->cctx)) 1377 if (expect_false (prev__cctx != next->cctx))
1386 { 1378 {
1387 prev__cctx->top_env = PL_top_env; 1379 prev__cctx->top_env = PL_top_env;
1388 PL_top_env = next->cctx->top_env; 1380 PL_top_env = next->cctx->top_env;
1784 PerlIOBuf_set_ptrcnt, 1776 PerlIOBuf_set_ptrcnt,
1785}; 1777};
1786 1778
1787/*****************************************************************************/ 1779/*****************************************************************************/
1788 1780
1789static const CV *slf_cv; /* for quick consistency check */
1790
1791static UNOP slf_restore; /* restore stack as entersub did, for first-re-run */ 1781static UNOP slf_restore; /* restore stack as entersub did, for first-re-run */
1782static const CV *slf_cv;
1792static SV *slf_arg0; 1783static SV **slf_argv;
1793static SV *slf_arg1; 1784static int slf_argc, slf_arga; /* count, allocated */
1794static SV *slf_arg2; 1785static I32 slf_ax; /* top of stack, for restore */
1795 1786
1796/* this restores the stack in the case we patched the entersub, to */ 1787/* this restores the stack in the case we patched the entersub, to */
1797/* recreate the stack frame as perl will on following calls */ 1788/* recreate the stack frame as perl will on following calls */
1798/* since entersub cleared the stack */ 1789/* since entersub cleared the stack */
1799static OP * 1790static OP *
1800pp_restore (pTHX) 1791pp_restore (pTHX)
1801{ 1792{
1802 dSP; 1793 int i;
1794 SV **SP = PL_stack_base + slf_ax;
1803 1795
1804 PUSHMARK (SP); 1796 PUSHMARK (SP);
1805 1797
1806 EXTEND (SP, 3); 1798 EXTEND (SP, slf_argc + 1);
1799
1800 for (i = 0; i < slf_argc; ++i)
1807 if (slf_arg0) PUSHs (sv_2mortal (slf_arg0)); 1801 PUSHs (sv_2mortal (slf_argv [i]));
1808 if (slf_arg1) PUSHs (sv_2mortal (slf_arg1)); 1802
1809 if (slf_arg2) PUSHs (sv_2mortal (slf_arg2));
1810 PUSHs ((SV *)CvGV (slf_cv)); 1803 PUSHs ((SV *)CvGV (slf_cv));
1811 1804
1812 RETURNOP (slf_restore.op_first); 1805 RETURNOP (slf_restore.op_first);
1813} 1806}
1814 1807
1896 /* do a quick consistency check on the "function" object, and if it isn't */ 1889 /* do a quick consistency check on the "function" object, and if it isn't */
1897 /* for us, divert to the real entersub */ 1890 /* for us, divert to the real entersub */
1898 if (SvTYPE (gv) != SVt_PVGV || !(CvFLAGS (GvCV (gv)) & CVf_SLF)) 1891 if (SvTYPE (gv) != SVt_PVGV || !(CvFLAGS (GvCV (gv)) & CVf_SLF))
1899 return PL_ppaddr[OP_ENTERSUB](aTHX); 1892 return PL_ppaddr[OP_ENTERSUB](aTHX);
1900 1893
1901 /* pop args */
1902 SP = PL_stack_base + POPMARK;
1903
1904 if (!(PL_op->op_flags & OPf_STACKED)) 1894 if (!(PL_op->op_flags & OPf_STACKED))
1905 { 1895 {
1906 /* ampersand-form of call, use @_ instead of stack */ 1896 /* ampersand-form of call, use @_ instead of stack */
1907 AV *av = GvAV (PL_defgv); 1897 AV *av = GvAV (PL_defgv);
1908 arg = AvARRAY (av); 1898 arg = AvARRAY (av);
1909 items = AvFILLp (av) + 1; 1899 items = AvFILLp (av) + 1;
1910 } 1900 }
1911 1901
1912 PUTBACK;
1913
1914 /* now call the init function, which needs to set up slf_frame */ 1902 /* now call the init function, which needs to set up slf_frame */
1915 ((coro_slf_cb)CvXSUBANY (GvCV (gv)).any_ptr) 1903 ((coro_slf_cb)CvXSUBANY (GvCV (gv)).any_ptr)
1916 (aTHX_ &slf_frame, GvCV (gv), arg, items); 1904 (aTHX_ &slf_frame, GvCV (gv), arg, items);
1905
1906 /* pop args */
1907 SP = PL_stack_base + POPMARK;
1908
1909 PUTBACK;
1917 } 1910 }
1918 1911
1919 /* now that we have a slf_frame, interpret it! */ 1912 /* now that we have a slf_frame, interpret it! */
1920 /* we use a callback system not to make the code needlessly */ 1913 /* we use a callback system not to make the code needlessly */
1921 /* complicated, but so we can run multiple perl coros from one cctx */ 1914 /* complicated, but so we can run multiple perl coros from one cctx */
1929 1922
1930 checkmark = PL_stack_sp - PL_stack_base; 1923 checkmark = PL_stack_sp - PL_stack_base;
1931 } 1924 }
1932 while (slf_frame.check (aTHX_ &slf_frame)); 1925 while (slf_frame.check (aTHX_ &slf_frame));
1933 1926
1927 slf_frame.prepare = 0; /* invalidate the frame, we are done processing it */
1928
1929 /* return value handling - mostly like entersub */
1934 { 1930 {
1935 dSP; 1931 dSP;
1936 SV **bot = PL_stack_base + checkmark; 1932 SV **bot = PL_stack_base + checkmark;
1937 int gimme = GIMME_V; 1933 int gimme = GIMME_V;
1938
1939 slf_frame.prepare = 0; /* invalidate the frame, so it gets initialised again next time */
1940 1934
1941 /* make sure we put something on the stack in scalar context */ 1935 /* make sure we put something on the stack in scalar context */
1942 if (gimme == G_SCALAR) 1936 if (gimme == G_SCALAR)
1943 { 1937 {
1944 if (sp == bot) 1938 if (sp == bot)
1948 } 1942 }
1949 1943
1950 PUTBACK; 1944 PUTBACK;
1951 } 1945 }
1952 1946
1947 /* exception handling */
1948 if (expect_false (coro_throw))
1949 {
1950 SV *exception = sv_2mortal (coro_throw);
1951
1952 coro_throw = 0;
1953 sv_setsv (ERRSV, exception);
1954 croak (0);
1955 }
1956
1953 return NORMAL; 1957 return NORMAL;
1954} 1958}
1955 1959
1956static void 1960static void
1957api_execute_slf (pTHX_ CV *cv, coro_slf_cb init_cb, SV **arg, int items) 1961api_execute_slf (pTHX_ CV *cv, coro_slf_cb init_cb, I32 ax)
1958{ 1962{
1963 int i;
1964 SV **arg = PL_stack_base + ax;
1965 int items = PL_stack_sp - arg + 1;
1966
1959 assert (("FATAL: SLF call with illegal CV value", !CvANON (cv))); 1967 assert (("FATAL: SLF call with illegal CV value", !CvANON (cv)));
1960 1968
1961 if (PL_op->op_ppaddr != PL_ppaddr [OP_ENTERSUB] 1969 if (PL_op->op_ppaddr != PL_ppaddr [OP_ENTERSUB]
1962 && PL_op->op_ppaddr != pp_slf) 1970 && PL_op->op_ppaddr != pp_slf)
1963 croak ("FATAL: Coro SLF calls can only be made normally, not via goto or any other means, caught"); 1971 croak ("FATAL: Coro SLF calls can only be made normally, not via goto or any other means, caught");
1964 1972
1965 if (items > 3)
1966 croak ("Coro only supports up to three arguments to SLF functions currently (not %d), caught", items);
1967
1968 CvFLAGS (cv) |= CVf_SLF; 1973 CvFLAGS (cv) |= CVf_SLF;
1969 CvXSUBANY (cv).any_ptr = (void *)init_cb; 1974 CvXSUBANY (cv).any_ptr = (void *)init_cb;
1970 slf_cv = cv; 1975 slf_cv = cv;
1971 1976
1972 /* we patch the op, and then re-run the whole call */ 1977 /* we patch the op, and then re-run the whole call */
1973 /* we have to put the same argument on the stack for this to work */ 1978 /* we have to put the same argument on the stack for this to work */
1974 /* and this will be done by pp_restore */ 1979 /* and this will be done by pp_restore */
1975 slf_restore.op_next = (OP *)&slf_restore; 1980 slf_restore.op_next = (OP *)&slf_restore;
1976 slf_restore.op_type = OP_CUSTOM; 1981 slf_restore.op_type = OP_CUSTOM;
1977 slf_restore.op_ppaddr = pp_restore; 1982 slf_restore.op_ppaddr = pp_restore;
1978 slf_restore.op_first = PL_op; 1983 slf_restore.op_first = PL_op;
1979 1984
1980 slf_arg0 = items > 0 ? SvREFCNT_inc (arg [0]) : 0; 1985 slf_ax = ax - 1; /* undo the ax++ inside dAXMARK */
1981 slf_arg1 = items > 1 ? SvREFCNT_inc (arg [1]) : 0; 1986
1982 slf_arg2 = items > 2 ? SvREFCNT_inc (arg [2]) : 0; 1987 if (PL_op->op_flags & OPf_STACKED)
1988 {
1989 if (items > slf_arga)
1990 {
1991 slf_arga = items;
1992 free (slf_argv);
1993 slf_argv = malloc (slf_arga * sizeof (SV *));
1994 }
1995
1996 slf_argc = items;
1997
1998 for (i = 0; i < items; ++i)
1999 slf_argv [i] = SvREFCNT_inc (arg [i]);
2000 }
2001 else
2002 slf_argc = 0;
1983 2003
1984 PL_op->op_ppaddr = pp_slf; 2004 PL_op->op_ppaddr = pp_slf;
2005 PL_op->op_type = OP_CUSTOM; /* maybe we should leave it at entersub? */
1985 2006
1986 PL_op = (OP *)&slf_restore; 2007 PL_op = (OP *)&slf_restore;
1987} 2008}
1988 2009
1989/*****************************************************************************/ 2010/*****************************************************************************/
2208 RETVAL 2229 RETVAL
2209 2230
2210void 2231void
2211_set_stacklevel (...) 2232_set_stacklevel (...)
2212 CODE: 2233 CODE:
2213 api_execute_slf (aTHX_ cv, slf_init_set_stacklevel, &ST (0), items); 2234 CORO_EXECUTE_SLF_XS (slf_init_set_stacklevel);
2214 2235
2215void 2236void
2216transfer (...) 2237transfer (...)
2217 PROTOTYPE: $$ 2238 PROTOTYPE: $$
2218 CODE: 2239 CODE:
2219 api_execute_slf (aTHX_ cv, slf_init_transfer, &ST (0), items); 2240 CORO_EXECUTE_SLF_XS (slf_init_transfer);
2220 2241
2221bool 2242bool
2222_destroy (SV *coro_sv) 2243_destroy (SV *coro_sv)
2223 CODE: 2244 CODE:
2224 RETVAL = coro_state_destroy (aTHX_ SvSTATE (coro_sv)); 2245 RETVAL = coro_state_destroy (aTHX_ SvSTATE (coro_sv));
2342 2363
2343void 2364void
2344throw (Coro::State self, SV *throw = &PL_sv_undef) 2365throw (Coro::State self, SV *throw = &PL_sv_undef)
2345 PROTOTYPE: $;$ 2366 PROTOTYPE: $;$
2346 CODE: 2367 CODE:
2368{
2369 struct coro *current = SvSTATE_current;
2370 SV **throwp = self == current ? &coro_throw : &self->throw;
2347 SvREFCNT_dec (self->throw); 2371 SvREFCNT_dec (*throwp);
2348 self->throw = SvOK (throw) ? newSVsv (throw) : 0; 2372 *throwp = SvOK (throw) ? newSVsv (throw) : 0;
2373}
2349 2374
2350void 2375void
2351api_trace (SV *coro, int flags = CC_TRACE | CC_TRACE_SUB) 2376api_trace (SV *coro, int flags = CC_TRACE | CC_TRACE_SUB)
2352 PROTOTYPE: $;$ 2377 PROTOTYPE: $;$
2353 C_ARGS: aTHX_ coro, flags 2378 C_ARGS: aTHX_ coro, flags
2447} 2472}
2448 2473
2449void 2474void
2450schedule (...) 2475schedule (...)
2451 CODE: 2476 CODE:
2452 api_execute_slf (aTHX_ cv, slf_init_schedule, &ST (0), 0); 2477 CORO_EXECUTE_SLF_XS (slf_init_schedule);
2453 2478
2454void 2479void
2455cede (...) 2480cede (...)
2456 CODE: 2481 CODE:
2457 api_execute_slf (aTHX_ cv, slf_init_cede, &ST (0), 0); 2482 CORO_EXECUTE_SLF_XS (slf_init_cede);
2458 2483
2459void 2484void
2460cede_notself (...) 2485cede_notself (...)
2461 CODE: 2486 CODE:
2462 api_execute_slf (aTHX_ cv, slf_init_cede_notself, &ST (0), 0); 2487 CORO_EXECUTE_SLF_XS (slf_init_cede_notself);
2463 2488
2464void 2489void
2465_set_current (SV *current) 2490_set_current (SV *current)
2466 PROTOTYPE: $ 2491 PROTOTYPE: $
2467 CODE: 2492 CODE:
2555 2580
2556void 2581void
2557_pool_2 (SV *cb) 2582_pool_2 (SV *cb)
2558 CODE: 2583 CODE:
2559{ 2584{
2560 struct coro *coro = SvSTATE_current; 2585 HV *hv = (HV *)SvRV (coro_current);
2586 struct coro *coro = SvSTATE_hv ((SV *)hv);
2561 2587
2562 sv_setsv (cb, &PL_sv_undef); 2588 sv_setsv (cb, &PL_sv_undef);
2563 2589
2564 SvREFCNT_dec ((SV *)PL_defoutgv); PL_defoutgv = (GV *)coro->saved_deffh; 2590 SvREFCNT_dec ((SV *)PL_defoutgv); PL_defoutgv = (GV *)coro->saved_deffh;
2565 coro->saved_deffh = 0; 2591 coro->saved_deffh = 0;
2572 SvREFCNT_dec (old); 2598 SvREFCNT_dec (old);
2573 croak ("\3async_pool terminate\2\n"); 2599 croak ("\3async_pool terminate\2\n");
2574 } 2600 }
2575 2601
2576 av_clear (GvAV (PL_defgv)); 2602 av_clear (GvAV (PL_defgv));
2577 hv_store ((HV *)SvRV (coro_current), "desc", sizeof ("desc") - 1, 2603 hv_store (hv, "desc", sizeof ("desc") - 1,
2578 newSVpvn ("[async_pool idle]", sizeof ("[async_pool idle]") - 1), 0); 2604 newSVpvn ("[async_pool idle]", sizeof ("[async_pool idle]") - 1), 0);
2579 2605
2580 coro->prio = 0; 2606 coro->prio = 0;
2581 2607
2582 if (coro->cctx && (coro->cctx->flags & CC_TRACE)) 2608 if (coro->cctx && (coro->cctx->flags & CC_TRACE))
2702 coro_semaphore_adjust (aTHX_ (AV *)SvRV (self), ix ? adjust : 1); 2728 coro_semaphore_adjust (aTHX_ (AV *)SvRV (self), ix ? adjust : 1);
2703 2729
2704void 2730void
2705down (SV *self) 2731down (SV *self)
2706 CODE: 2732 CODE:
2707 api_execute_slf (aTHX_ cv, slf_init_semaphore_down, &ST (0), 1); 2733 CORO_EXECUTE_SLF_XS (slf_init_semaphore_down);
2708 2734
2709void 2735void
2710try (SV *self) 2736try (SV *self)
2711 PPCODE: 2737 PPCODE:
2712{ 2738{

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines