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.413 by root, Fri Jun 17 18:55:08 2011 UTC vs.
Revision 1.424 by root, Fri Nov 30 19:27:28 2012 UTC

12#include "perl.h" 12#include "perl.h"
13#include "XSUB.h" 13#include "XSUB.h"
14#include "perliol.h" 14#include "perliol.h"
15 15
16#include "schmorp.h" 16#include "schmorp.h"
17
18#define ECB_NO_THREADS 1
17#include "ecb.h" 19#include "ecb.h"
18 20
19#include <stddef.h> 21#include <stddef.h>
20#include <stdio.h> 22#include <stdio.h>
21#include <errno.h> 23#include <errno.h>
63#endif 65#endif
64 66
65/* the maximum number of idle cctx that will be pooled */ 67/* the maximum number of idle cctx that will be pooled */
66static int cctx_max_idle = 4; 68static int cctx_max_idle = 4;
67 69
70#if defined(DEBUGGING) && PERL_VERSION_ATLEAST(5,12,0)
71# define HAS_SCOPESTACK_NAME 1
72#endif
73
68#if !__i386 && !__x86_64 && !__powerpc && !__m68k && !__alpha && !__mips && !__sparc64 74#if !__i386 && !__x86_64 && !__powerpc && !__m68k && !__alpha && !__mips && !__sparc64
69# undef CORO_STACKGUARD 75# undef CORO_STACKGUARD
70#endif 76#endif
71 77
72#ifndef CORO_STACKGUARD 78#ifndef CORO_STACKGUARD
97# if CORO_PTHREAD 103# if CORO_PTHREAD
98static void *coro_thx; 104static void *coro_thx;
99# endif 105# endif
100#endif 106#endif
101 107
102/* used in state.h */
103#define VAR(name,type) VARx(name, PL_ ## name, type)
104
105#ifdef __linux 108#ifdef __linux
106# include <time.h> /* for timespec */ 109# include <time.h> /* for timespec */
107# include <syscall.h> /* for SYS_* */ 110# include <syscall.h> /* for SYS_* */
108# ifdef SYS_clock_gettime 111# ifdef SYS_clock_gettime
109# define coro_clock_gettime(id, ts) syscall (SYS_clock_gettime, (id), (ts)) 112# define coro_clock_gettime(id, ts) syscall (SYS_clock_gettime, (id), (ts))
177 void *sptr; 180 void *sptr;
178 size_t ssize; 181 size_t ssize;
179 182
180 /* cpu state */ 183 /* cpu state */
181 void *idle_sp; /* sp of top-level transfer/schedule/cede call */ 184 void *idle_sp; /* sp of top-level transfer/schedule/cede call */
185#ifndef NDEBUG
182 JMPENV *idle_te; /* same as idle_sp, but for top_env, TODO: remove once stable */ 186 JMPENV *idle_te; /* same as idle_sp, but for top_env */
187#endif
183 JMPENV *top_env; 188 JMPENV *top_env;
184 coro_context cctx; 189 coro_context cctx;
185 190
186 U32 gen; 191 U32 gen;
187#if CORO_USE_VALGRIND 192#if CORO_USE_VALGRIND
207}; 212};
208 213
209/* the structure where most of the perl state is stored, overlaid on the cxstack */ 214/* the structure where most of the perl state is stored, overlaid on the cxstack */
210typedef struct 215typedef struct
211{ 216{
212#define VARx(name,expr,type) type name; 217 #define VARx(name,expr,type) type name;
213# include "state.h" 218 #include "state.h"
214#undef VARx
215} perl_slots; 219} perl_slots;
216 220
217/* how many context stack entries do we need for perl_slots */ 221/* how many context stack entries do we need for perl_slots */
218#define SLOT_COUNT ((sizeof (perl_slots) + sizeof (PERL_CONTEXT) - 1) / sizeof (PERL_CONTEXT)) 222#define SLOT_COUNT ((sizeof (perl_slots) + sizeof (PERL_CONTEXT) - 1) / sizeof (PERL_CONTEXT))
219 223
369time_init (pTHX) 373time_init (pTHX)
370{ 374{
371 SV **svp; 375 SV **svp;
372 376
373 require_pv ("Time/HiRes.pm"); 377 require_pv ("Time/HiRes.pm");
374 378
375 svp = hv_fetch (PL_modglobal, "Time::NVtime", 12, 0); 379 svp = hv_fetch (PL_modglobal, "Time::NVtime", 12, 0);
376 380
377 if (!svp) croak ("Time::HiRes is required, but missing. Caught"); 381 if (!svp) croak ("Time::HiRes is required, but missing. Caught");
378 if (!SvIOK (*svp)) croak ("Time::NVtime isn't a function pointer. Caught"); 382 if (!SvIOK (*svp)) croak ("Time::NVtime isn't a function pointer. Caught");
379 383
637 AvARRAY (av)[++AvFILLp (av)] = (SV *)CvPADLIST (cv); 641 AvARRAY (av)[++AvFILLp (av)] = (SV *)CvPADLIST (cv);
638} 642}
639 643
640/** load & save, init *******************************************************/ 644/** load & save, init *******************************************************/
641 645
646ecb_inline void
647swap_sv (SV *a, SV *b)
648{
649 const U32 keep = SVs_PADSTALE | SVs_PADTMP | SVs_PADMY; /* keep these flags */
650 SV tmp;
651
652 /* swap sv_any */
653 SvANY (&tmp) = SvANY (a); SvANY (a) = SvANY (b); SvANY (b) = SvANY (&tmp);
654
655 /* swap sv_flags */
656 SvFLAGS (&tmp) = SvFLAGS (a);
657 SvFLAGS (a) = (SvFLAGS (a) & keep) | (SvFLAGS (b ) & ~keep);
658 SvFLAGS (b) = (SvFLAGS (b) & keep) | (SvFLAGS (&tmp) & ~keep);
659
660#if PERL_VERSION_ATLEAST (5,10,0)
661 /* perl 5.10 and later complicates this _quite_ a bit, but it also
662 * is much faster, so no quarrels here. alternatively, we could
663 * sv_upgrade to avoid this.
664 */
665 {
666 /* swap sv_u */
667 tmp.sv_u = a->sv_u; a->sv_u = b->sv_u; b->sv_u = tmp.sv_u;
668
669 /* if SvANY points to the head, we need to adjust the pointers,
670 * as the pointer for a still points to b, and maybe vice versa.
671 */
672 #define svany_in_head(type) \
673 (((1 << SVt_NULL) | (1 << SVt_BIND) | (1 << SVt_IV) | (1 << SVt_RV)) & (1 << (type)))
674
675 if (svany_in_head (SvTYPE (a)))
676 SvANY (a) = (void *)((PTRV)SvANY (a) - (PTRV)b + (PTRV)a);
677
678 if (svany_in_head (SvTYPE (b)))
679 SvANY (b) = (void *)((PTRV)SvANY (b) - (PTRV)a + (PTRV)b);
680 }
681#endif
682}
683
642/* swap sv heads, at least logically */ 684/* swap sv heads, at least logically */
643static void 685static void
644swap_svs (pTHX_ Coro__State c) 686swap_svs (pTHX_ Coro__State c)
645{ 687{
646 int i; 688 int i;
647 689
648 for (i = 0; i <= AvFILLp (c->swap_sv); ) 690 for (i = 0; i <= AvFILLp (c->swap_sv); i += 2)
649 { 691 swap_sv (AvARRAY (c->swap_sv)[i], AvARRAY (c->swap_sv)[i + 1]);
650 SV *a = AvARRAY (c->swap_sv)[i++];
651 SV *b = AvARRAY (c->swap_sv)[i++];
652
653 const U32 keep = SVs_PADSTALE | SVs_PADTMP | SVs_PADMY; /* keep these flags */
654 SV tmp;
655
656 /* swap sv_any */
657 SvANY (&tmp) = SvANY (a); SvANY (a) = SvANY (b); SvANY (b) = SvANY (&tmp);
658
659 /* swap sv_flags */
660 SvFLAGS (&tmp) = SvFLAGS (a);
661 SvFLAGS (a) = (SvFLAGS (a) & keep) | (SvFLAGS (b ) & ~keep);
662 SvFLAGS (b) = (SvFLAGS (b) & keep) | (SvFLAGS (&tmp) & ~keep);
663
664#if PERL_VERSION_ATLEAST (5,10,0)
665 /* perl 5.10 complicates this _quite_ a bit, but it also is
666 * much faster, so no quarrels here. alternatively, we could
667 * sv_upgrade to avoid this.
668 */
669 {
670 /* swap sv_u */
671 tmp.sv_u = a->sv_u; a->sv_u = b->sv_u; b->sv_u = tmp.sv_u;
672
673 /* if SvANY points to the head, we need to adjust the pointers,
674 * as the pointer for a still points to b, and maybe vice versa.
675 */
676 #define svany_in_head(type) \
677 (((1 << SVt_NULL) | (1 << SVt_BIND) | (1 << SVt_IV) | (1 << SVt_RV)) & (1 << (type)))
678
679 if (svany_in_head (SvTYPE (a)))
680 SvANY (a) = (void *)((PTRV)SvANY (a) - (PTRV)b + (PTRV)a);
681
682 if (svany_in_head (SvTYPE (b)))
683 SvANY (b) = (void *)((PTRV)SvANY (b) - (PTRV)a + (PTRV)b);
684 }
685#endif
686 }
687} 692}
688 693
689#define SWAP_SVS(coro) \ 694#define SWAP_SVS(coro) \
690 if (ecb_expect_false ((coro)->swap_sv)) \ 695 if (ecb_expect_false ((coro)->swap_sv)) \
691 swap_svs (aTHX_ (coro)) 696 swap_svs (aTHX_ (coro))
703 708
704#if CORO_JIT 709#if CORO_JIT
705 load_perl_slots (slot); 710 load_perl_slots (slot);
706#else 711#else
707 #define VARx(name,expr,type) expr = slot->name; 712 #define VARx(name,expr,type) expr = slot->name;
708 # include "state.h" 713 #include "state.h"
709 #undef VARx
710#endif 714#endif
711 715
712 { 716 {
713 dSP; 717 dSP;
714 718
836 840
837#if CORO_JIT 841#if CORO_JIT
838 save_perl_slots (slot); 842 save_perl_slots (slot);
839#else 843#else
840 #define VARx(name,expr,type) slot->name = expr; 844 #define VARx(name,expr,type) slot->name = expr;
841 # include "state.h" 845 #include "state.h"
842 #undef VARx
843#endif 846#endif
844 } 847 }
845} 848}
846 849
847/* 850/*
879#endif 882#endif
880 883
881 New(54,PL_scopestack,8,I32); 884 New(54,PL_scopestack,8,I32);
882 PL_scopestack_ix = 0; 885 PL_scopestack_ix = 0;
883 PL_scopestack_max = 8; 886 PL_scopestack_max = 8;
887#if HAS_SCOPESTACK_NAME
888 New(54,PL_scopestack_name,8,const char*);
889#endif
884 890
885 New(54,PL_savestack,24,ANY); 891 New(54,PL_savestack,24,ANY);
886 PL_savestack_ix = 0; 892 PL_savestack_ix = 0;
887 PL_savestack_max = 24; 893 PL_savestack_max = 24;
888 894
916 } 922 }
917 923
918 Safefree (PL_tmps_stack); 924 Safefree (PL_tmps_stack);
919 Safefree (PL_markstack); 925 Safefree (PL_markstack);
920 Safefree (PL_scopestack); 926 Safefree (PL_scopestack);
927#if HAS_SCOPESTACK_NAME
928 Safefree (PL_scopestack_name);
929#endif
921 Safefree (PL_savestack); 930 Safefree (PL_savestack);
922#if !PERL_VERSION_ATLEAST (5,10,0) 931#if !PERL_VERSION_ATLEAST (5,10,0)
923 Safefree (PL_retstack); 932 Safefree (PL_retstack);
924#endif 933#endif
925} 934}
985 { 994 {
986 SV **svp = 0; 995 SV **svp = 0;
987 996
988 if (strEQ (s, "__DIE__" )) svp = &PL_diehook; 997 if (strEQ (s, "__DIE__" )) svp = &PL_diehook;
989 if (strEQ (s, "__WARN__")) svp = &PL_warnhook; 998 if (strEQ (s, "__WARN__")) svp = &PL_warnhook;
990 999
991 if (svp) 1000 if (svp)
992 { 1001 {
993 sv_setsv (sv, *svp ? *svp : &PL_sv_undef); 1002 SV *ssv;
1003
1004 if (!*svp)
1005 ssv = &PL_sv_undef;
1006 else if (SvTYPE (*svp) == SVt_PVCV) /* perlio directly stores a CV in warnhook. ugh. */
1007 ssv = sv_2mortal (newRV_inc (*svp));
1008 else
1009 ssv = *svp;
1010
1011 sv_setsv (sv, ssv);
994 return 0; 1012 return 0;
995 } 1013 }
996 } 1014 }
997 1015
998 return orig_sigelem_get ? orig_sigelem_get (aTHX_ sv, mg) : 0; 1016 return orig_sigelem_get ? orig_sigelem_get (aTHX_ sv, mg) : 0;
1092 PL_hints = 0; 1110 PL_hints = 0;
1093 1111
1094 /* recreate the die/warn hooks */ 1112 /* recreate the die/warn hooks */
1095 PL_diehook = SvREFCNT_inc (rv_diehook); 1113 PL_diehook = SvREFCNT_inc (rv_diehook);
1096 PL_warnhook = SvREFCNT_inc (rv_warnhook); 1114 PL_warnhook = SvREFCNT_inc (rv_warnhook);
1097 1115
1098 GvSV (PL_defgv) = newSV (0); 1116 GvSV (PL_defgv) = newSV (0);
1099 GvAV (PL_defgv) = coro->args; coro->args = 0; 1117 GvAV (PL_defgv) = coro->args; coro->args = 0;
1100 GvSV (PL_errgv) = newSV (0); 1118 GvSV (PL_errgv) = newSV (0);
1101 GvSV (irsgv) = newSVpvn ("\n", 1); sv_magic (GvSV (irsgv), (SV *)irsgv, PERL_MAGIC_sv, "/", 0); 1119 GvSV (irsgv) = newSVpvn ("\n", 1); sv_magic (GvSV (irsgv), (SV *)irsgv, PERL_MAGIC_sv, "/", 0);
1102 GvHV (PL_hintgv) = 0; 1120 GvHV (PL_hintgv) = 0;
1395transfer_tail (pTHX) 1413transfer_tail (pTHX)
1396{ 1414{
1397 free_coro_mortal (aTHX); 1415 free_coro_mortal (aTHX);
1398} 1416}
1399 1417
1418/* try to exit the same way perl's main function would do */
1419/* we do not bother resetting the environment or other things *7
1420/* that are not, uhm, essential */
1421/* this obviously also doesn't work when perl is embedded */
1422static void ecb_noinline ecb_cold
1423perlish_exit (pTHX)
1424{
1425 int exitstatus = perl_destruct (PL_curinterp);
1426 perl_free (PL_curinterp);
1427 exit (exitstatus);
1428}
1429
1400/* 1430/*
1401 * this is a _very_ stripped down perl interpreter ;) 1431 * this is a _very_ stripped down perl interpreter ;)
1402 */ 1432 */
1403static void 1433static void
1404cctx_run (void *arg) 1434cctx_run (void *arg)
1431 */ 1461 */
1432 1462
1433 /* 1463 /*
1434 * If perl-run returns we assume exit() was being called or the coro 1464 * If perl-run returns we assume exit() was being called or the coro
1435 * fell off the end, which seems to be the only valid (non-bug) 1465 * fell off the end, which seems to be the only valid (non-bug)
1436 * reason for perl_run to return. We try to exit by jumping to the 1466 * reason for perl_run to return. We try to mimic whatever perl is normally
1437 * bootstrap-time "top" top_env, as we cannot restore the "main" 1467 * doing in that case. YMMV.
1438 * coroutine as Coro has no such concept.
1439 * This actually isn't valid with the pthread backend, but OSes requiring
1440 * that backend are too broken to do it in a standards-compliant way.
1441 */ 1468 */
1442 PL_top_env = main_top_env; 1469 perlish_exit (aTHX);
1443 JMPENV_JUMP (2); /* I do not feel well about the hardcoded 2 at all */
1444 } 1470 }
1445} 1471}
1446 1472
1447static coro_cctx * 1473static coro_cctx *
1448cctx_new (void) 1474cctx_new (void)
1480 size_t stack_size; 1506 size_t stack_size;
1481 1507
1482#if HAVE_MMAP 1508#if HAVE_MMAP
1483 cctx->ssize = ((cctx_stacksize * sizeof (long) + PAGESIZE - 1) / PAGESIZE + CORO_STACKGUARD) * PAGESIZE; 1509 cctx->ssize = ((cctx_stacksize * sizeof (long) + PAGESIZE - 1) / PAGESIZE + CORO_STACKGUARD) * PAGESIZE;
1484 /* mmap supposedly does allocate-on-write for us */ 1510 /* mmap supposedly does allocate-on-write for us */
1485 cctx->sptr = mmap (0, cctx->ssize, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANONYMOUS, 0, 0); 1511 cctx->sptr = mmap (0, cctx->ssize, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANONYMOUS, -1, 0);
1486 1512
1487 if (cctx->sptr != (void *)-1) 1513 if (cctx->sptr != (void *)-1)
1488 { 1514 {
1489 #if CORO_STACKGUARD 1515 #if CORO_STACKGUARD
1490 mprotect (cctx->sptr, CORO_STACKGUARD * PAGESIZE, PROT_NONE); 1516 mprotect (cctx->sptr, CORO_STACKGUARD * PAGESIZE, PROT_NONE);
1705 return; 1731 return;
1706 1732
1707 slf_destroy (aTHX_ coro); 1733 slf_destroy (aTHX_ coro);
1708 1734
1709 coro->flags |= CF_ZOMBIE; 1735 coro->flags |= CF_ZOMBIE;
1710 1736
1711 if (coro->flags & CF_READY) 1737 if (coro->flags & CF_READY)
1712 { 1738 {
1713 /* reduce nready, as destroying a ready coro effectively unreadies it */ 1739 /* reduce nready, as destroying a ready coro effectively unreadies it */
1714 /* alternative: look through all ready queues and remove the coro */ 1740 /* alternative: look through all ready queues and remove the coro */
1715 --coro_nready; 1741 --coro_nready;
2148 2174
2149static void 2175static void
2150coro_set_status (pTHX_ struct coro *coro, SV **arg, int items) 2176coro_set_status (pTHX_ struct coro *coro, SV **arg, int items)
2151{ 2177{
2152 AV *av; 2178 AV *av;
2153 2179
2154 if (coro->status) 2180 if (coro->status)
2155 { 2181 {
2156 av = coro->status; 2182 av = coro->status;
2157 av_clear (av); 2183 av_clear (av);
2158 } 2184 }
2205 2231
2206 coro = SvSTATE (arg [0]); 2232 coro = SvSTATE (arg [0]);
2207 coro_hv = coro->hv; 2233 coro_hv = coro->hv;
2208 2234
2209 coro_set_status (aTHX_ coro, arg + 1, items - 1); 2235 coro_set_status (aTHX_ coro, arg + 1, items - 1);
2210 2236
2211 if (ecb_expect_false (coro->flags & CF_NOCANCEL)) 2237 if (ecb_expect_false (coro->flags & CF_NOCANCEL))
2212 { 2238 {
2213 /* coro currently busy cancelling something, so just notify it */ 2239 /* coro currently busy cancelling something, so just notify it */
2214 coro->slf_frame.data = (void *)coro; 2240 coro->slf_frame.data = (void *)coro;
2215 2241
2394 2420
2395static int 2421static int
2396slf_check_rouse_wait (pTHX_ struct CoroSLF *frame) 2422slf_check_rouse_wait (pTHX_ struct CoroSLF *frame)
2397{ 2423{
2398 SV *data = (SV *)frame->data; 2424 SV *data = (SV *)frame->data;
2399 2425
2400 if (CORO_THROW) 2426 if (CORO_THROW)
2401 return 0; 2427 return 0;
2402 2428
2403 if (SvTYPE (SvRV (data)) != SVt_PVAV) 2429 if (SvTYPE (SvRV (data)) != SVt_PVAV)
2404 return 1; 2430 return 1;
2440 cb = sv_2mortal (coro->rouse_cb); 2466 cb = sv_2mortal (coro->rouse_cb);
2441 coro->rouse_cb = 0; 2467 coro->rouse_cb = 0;
2442 } 2468 }
2443 2469
2444 if (!SvROK (cb) 2470 if (!SvROK (cb)
2445 || SvTYPE (SvRV (cb)) != SVt_PVCV 2471 || SvTYPE (SvRV (cb)) != SVt_PVCV
2446 || CvXSUB ((CV *)SvRV (cb)) != coro_rouse_callback) 2472 || CvXSUB ((CV *)SvRV (cb)) != coro_rouse_callback)
2447 croak ("Coro::rouse_wait called with illegal callback argument,"); 2473 croak ("Coro::rouse_wait called with illegal callback argument,");
2448 2474
2449 { 2475 {
2450 CV *cv = (CV *)SvRV (cb); /* for S_GENSUB_ARG */ 2476 CV *cv = (CV *)SvRV (cb); /* for S_GENSUB_ARG */
3371 int count; 3397 int count;
3372 3398
3373 eval_pv ("require 'Coro/jit-" CORO_JIT_TYPE ".pl'", 1); 3399 eval_pv ("require 'Coro/jit-" CORO_JIT_TYPE ".pl'", 1);
3374 3400
3375 PUSHMARK (SP); 3401 PUSHMARK (SP);
3376#define VARx(name,expr,type) pushav_4uv (aTHX_ (UV)&(expr), sizeof (expr), offsetof (perl_slots, name), sizeof (type)); 3402 #define VARx(name,expr,type) pushav_4uv (aTHX_ (UV)&(expr), sizeof (expr), offsetof (perl_slots, name), sizeof (type));
3377# include "state.h" 3403 #include "state.h"
3378#undef VARx
3379 count = call_pv ("Coro::State::_jit", G_ARRAY); 3404 count = call_pv ("Coro::State::_jit", G_ARRAY);
3380 SPAGAIN; 3405 SPAGAIN;
3381 3406
3382 save = POPs; save_ptr = SvPVbyte (save, save_len); 3407 save = POPs; save_ptr = SvPVbyte (save, save_len);
3383 load = POPs; load_ptr = SvPVbyte (load, load_len); 3408 load = POPs; load_ptr = SvPVbyte (load, load_len);
3640 RETVAL = boolSV (coro->flags & ix); 3665 RETVAL = boolSV (coro->flags & ix);
3641 OUTPUT: 3666 OUTPUT:
3642 RETVAL 3667 RETVAL
3643 3668
3644void 3669void
3645throw (Coro::State self, SV *exception = &PL_sv_undef) 3670throw (SV *self, SV *exception = &PL_sv_undef)
3646 PROTOTYPE: $;$ 3671 PROTOTYPE: $;$
3647 CODE: 3672 CODE:
3648{ 3673{
3674 struct coro *coro = SvSTATE (self);
3649 struct coro *current = SvSTATE_current; 3675 struct coro *current = SvSTATE_current;
3650 SV **exceptionp = self == current ? &CORO_THROW : &self->except; 3676 SV **exceptionp = coro == current ? &CORO_THROW : &coro->except;
3651 SvREFCNT_dec (*exceptionp); 3677 SvREFCNT_dec (*exceptionp);
3652 SvGETMAGIC (exception); 3678 SvGETMAGIC (exception);
3653 *exceptionp = SvOK (exception) ? newSVsv (exception) : 0; 3679 *exceptionp = SvOK (exception) ? newSVsv (exception) : 0;
3680
3681 api_ready (aTHX_ self);
3654} 3682}
3655 3683
3656void 3684void
3657api_trace (SV *coro, int flags = CC_TRACE | CC_TRACE_SUB) 3685api_trace (SV *coro, int flags = CC_TRACE | CC_TRACE_SUB)
3658 PROTOTYPE: $;$ 3686 PROTOTYPE: $;$
3788 3816
3789 sv_async_pool_idle = newSVpv ("[async pool idle]", 0); SvREADONLY_on (sv_async_pool_idle); 3817 sv_async_pool_idle = newSVpv ("[async pool idle]", 0); SvREADONLY_on (sv_async_pool_idle);
3790 sv_Coro = newSVpv ("Coro", 0); SvREADONLY_on (sv_Coro); 3818 sv_Coro = newSVpv ("Coro", 0); SvREADONLY_on (sv_Coro);
3791 cv_pool_handler = get_cv ("Coro::pool_handler", GV_ADD); SvREADONLY_on (cv_pool_handler); 3819 cv_pool_handler = get_cv ("Coro::pool_handler", GV_ADD); SvREADONLY_on (cv_pool_handler);
3792 CvNODEBUG_on (get_cv ("Coro::_pool_handler", 0)); /* work around a debugger bug */ 3820 CvNODEBUG_on (get_cv ("Coro::_pool_handler", 0)); /* work around a debugger bug */
3793 3821
3794 coro_stash = gv_stashpv ("Coro", TRUE); 3822 coro_stash = gv_stashpv ("Coro", TRUE);
3795 3823
3796 newCONSTSUB (coro_stash, "PRIO_MAX", newSViv (CORO_PRIO_MAX)); 3824 newCONSTSUB (coro_stash, "PRIO_MAX", newSViv (CORO_PRIO_MAX));
3797 newCONSTSUB (coro_stash, "PRIO_HIGH", newSViv (CORO_PRIO_HIGH)); 3825 newCONSTSUB (coro_stash, "PRIO_HIGH", newSViv (CORO_PRIO_HIGH));
3798 newCONSTSUB (coro_stash, "PRIO_NORMAL", newSViv (CORO_PRIO_NORMAL)); 3826 newCONSTSUB (coro_stash, "PRIO_NORMAL", newSViv (CORO_PRIO_NORMAL));

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines