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.5 by root, Tue Jul 17 02:55:29 2001 UTC vs.
Revision 1.307 by root, Wed Nov 19 14:34:46 2008 UTC

1#include "libcoro/coro.c"
2
3#define PERL_NO_GET_CONTEXT
4#define PERL_EXT
5
1#include "EXTERN.h" 6#include "EXTERN.h"
2#include "perl.h" 7#include "perl.h"
3#include "XSUB.h" 8#include "XSUB.h"
9#include "perliol.h"
4 10
5#if 0 11#include "patchlevel.h"
6# define CHK(x) (void *)0 12
13#include <stdio.h>
14#include <errno.h>
15#include <assert.h>
16
17#ifdef WIN32
18# undef setjmp
19# undef longjmp
20# undef _exit
21# define setjmp _setjmp /* deep magic */
7#else 22#else
8# define CHK(x) if (!(x)) croak("FATAL, CHK: " #x) 23# include <inttypes.h> /* most portable stdint.h */
24#endif
25
26#ifdef HAVE_MMAP
27# include <unistd.h>
28# include <sys/mman.h>
29# ifndef MAP_ANONYMOUS
30# ifdef MAP_ANON
31# define MAP_ANONYMOUS MAP_ANON
32# else
33# undef HAVE_MMAP
34# endif
9#endif 35# endif
36# include <limits.h>
37# ifndef PAGESIZE
38# define PAGESIZE pagesize
39# define BOOT_PAGESIZE pagesize = sysconf (_SC_PAGESIZE)
40static long pagesize;
41# else
42# define BOOT_PAGESIZE (void)0
43# endif
44#else
45# define PAGESIZE 0
46# define BOOT_PAGESIZE (void)0
47#endif
10 48
49#if CORO_USE_VALGRIND
50# include <valgrind/valgrind.h>
51#endif
52
53/* the maximum number of idle cctx that will be pooled */
54static int cctx_max_idle = 4;
55
56#define PERL_VERSION_ATLEAST(a,b,c) \
57 (PERL_REVISION > (a) \
58 || (PERL_REVISION == (a) \
59 && (PERL_VERSION > (b) \
60 || (PERL_VERSION == (b) && PERLSUBVERSION >= (c)))))
61
62#if !PERL_VERSION_ATLEAST (5,6,0)
63# ifndef PL_ppaddr
64# define PL_ppaddr ppaddr
65# endif
66# ifndef call_sv
67# define call_sv perl_call_sv
68# endif
69# ifndef get_sv
70# define get_sv perl_get_sv
71# endif
72# ifndef get_cv
73# define get_cv perl_get_cv
74# endif
75# ifndef IS_PADGV
76# define IS_PADGV(v) 0
77# endif
78# ifndef IS_PADCONST
79# define IS_PADCONST(v) 0
80# endif
81#endif
82
83/* 5.11 */
84#ifndef CxHASARGS
85# define CxHASARGS(cx) (cx)->blk_sub.hasargs
86#endif
87
88/* 5.10.0 */
89#ifndef SvREFCNT_inc_NN
90# define SvREFCNT_inc_NN(sv) SvREFCNT_inc (sv)
91#endif
92
93/* 5.8.8 */
94#ifndef GV_NOTQUAL
95# define GV_NOTQUAL 0
96#endif
97#ifndef newSV
98# define newSV(l) NEWSV(0,l)
99#endif
100#ifndef CvISXSUB_on
101# define CvISXSUB_on(cv) (void)cv
102#endif
103
104/* 5.8.7 */
105#ifndef SvRV_set
106# define SvRV_set(s,v) SvRV(s) = (v)
107#endif
108
109#if !__i386 && !__x86_64 && !__powerpc && !__m68k && !__alpha && !__mips && !__sparc64
110# undef CORO_STACKGUARD
111#endif
112
113#ifndef CORO_STACKGUARD
114# define CORO_STACKGUARD 0
115#endif
116
117/* prefer perl internal functions over our own? */
118#ifndef CORO_PREFER_PERL_FUNCTIONS
119# define CORO_PREFER_PERL_FUNCTIONS 0
120#endif
121
122/* The next macros try to return the current stack pointer, in an as
123 * portable way as possible. */
124#if __GNUC__ >= 4
125# define dSTACKLEVEL int stacklevel_dummy
126# define STACKLEVEL __builtin_frame_address (0)
127#else
128# define dSTACKLEVEL volatile void *stacklevel
129# define STACKLEVEL ((void *)&stacklevel)
130#endif
131
132#define IN_DESTRUCT (PL_main_cv == Nullcv)
133
134#if __GNUC__ >= 3
135# define attribute(x) __attribute__(x)
136# define expect(expr,value) __builtin_expect ((expr),(value))
137# define INLINE static inline
138#else
139# define attribute(x)
140# define expect(expr,value) (expr)
141# define INLINE static
142#endif
143
144#define expect_false(expr) expect ((expr) != 0, 0)
145#define expect_true(expr) expect ((expr) != 0, 1)
146
147#define NOINLINE attribute ((noinline))
148
149#include "CoroAPI.h"
150#define GCoroAPI (&coroapi) /* very sneaky */
151
152#ifdef USE_ITHREADS
153# if CORO_PTHREAD
154static void *coro_thx;
155# endif
156#endif
157
158static double (*nvtime)(); /* so why doesn't it take void? */
159
160/* we hijack an hopefully unused CV flag for our purposes */
161#define CVf_SLF 0x4000
162static OP *pp_slf (pTHX);
163
164static U32 cctx_gen;
165static size_t cctx_stacksize = CORO_STACKSIZE;
166static struct CoroAPI coroapi;
167static AV *main_mainstack; /* used to differentiate between $main and others */
168static JMPENV *main_top_env;
169static HV *coro_state_stash, *coro_stash;
170static volatile SV *coro_mortal; /* will be freed/thrown after next transfer */
171
172static GV *irsgv; /* $/ */
173static GV *stdoutgv; /* *STDOUT */
174static SV *rv_diehook;
175static SV *rv_warnhook;
176static HV *hv_sig; /* %SIG */
177
178/* async_pool helper stuff */
179static SV *sv_pool_rss;
180static SV *sv_pool_size;
181static AV *av_async_pool;
182
183/* Coro::AnyEvent */
184static SV *sv_activity;
185
186static struct coro_cctx *cctx_first;
187static int cctx_count, cctx_idle;
188
189enum {
190 CC_MAPPED = 0x01,
191 CC_NOREUSE = 0x02, /* throw this away after tracing */
192 CC_TRACE = 0x04,
193 CC_TRACE_SUB = 0x08, /* trace sub calls */
194 CC_TRACE_LINE = 0x10, /* trace each statement */
195 CC_TRACE_ALL = CC_TRACE_SUB | CC_TRACE_LINE,
196};
197
198/* this is a structure representing a c-level coroutine */
199typedef struct coro_cctx
200{
201 struct coro_cctx *next;
202
203 /* the stack */
204 void *sptr;
205 size_t ssize;
206
207 /* cpu state */
208 void *idle_sp; /* sp of top-level transfer/schedule/cede call */
209 JMPENV *idle_te; /* same as idle_sp, but for top_env, TODO: remove once stable */
210 JMPENV *top_env;
211 coro_context cctx;
212
213 U32 gen;
214#if CORO_USE_VALGRIND
215 int valgrind_id;
216#endif
217 unsigned char flags;
218} coro_cctx;
219
220enum {
221 CF_RUNNING = 0x0001, /* coroutine is running */
222 CF_READY = 0x0002, /* coroutine is ready */
223 CF_NEW = 0x0004, /* has never been switched to */
224 CF_DESTROYED = 0x0008, /* coroutine data has been freed */
225};
226
227/* the structure where most of the perl state is stored, overlaid on the cxstack */
228typedef struct
229{
230 SV *defsv;
231 AV *defav;
232 SV *errsv;
233 SV *irsgv;
234#define VAR(name,type) type name;
235# include "state.h"
236#undef VAR
237} perl_slots;
238
239#define SLOT_COUNT ((sizeof (perl_slots) + sizeof (PERL_CONTEXT) - 1) / sizeof (PERL_CONTEXT))
240
241/* this is a structure representing a perl-level coroutine */
11struct coro { 242struct coro {
12 U8 dowarn; 243 /* the C coroutine allocated to this perl coroutine, if any */
13 AV *defav; 244 coro_cctx *cctx;
14 245
15 PERL_SI *curstackinfo; 246 /* state data */
16 AV *curstack; 247 struct CoroSLF slf_frame; /* saved slf frame */
17 AV *mainstack; 248 AV *mainstack;
18 SV **stack_sp; 249 perl_slots *slot; /* basically the saved sp */
19 OP *op;
20 SV **curpad;
21 SV **stack_base;
22 SV **stack_max;
23 SV **tmps_stack;
24 I32 tmps_floor;
25 I32 tmps_ix;
26 I32 tmps_max;
27 I32 *markstack;
28 I32 *markstack_ptr;
29 I32 *markstack_max;
30 I32 *scopestack;
31 I32 scopestack_ix;
32 I32 scopestack_max;
33 ANY *savestack;
34 I32 savestack_ix;
35 I32 savestack_max;
36 OP **retstack;
37 I32 retstack_ix;
38 I32 retstack_max;
39 COP *curcop;
40 250
41 AV *args; 251 CV *startcv; /* the CV to execute */
252 AV *args; /* data associated with this coroutine (initial args) */
253 int refcnt; /* coroutines are refcounted, yes */
254 int flags; /* CF_ flags */
255 HV *hv; /* the perl hash associated with this coro, if any */
256 void (*on_destroy)(pTHX_ struct coro *coro);
257
258 /* statistics */
259 int usecount; /* number of transfers to this coro */
260
261 /* coro process data */
262 int prio;
263 SV *except; /* exception to be thrown */
264 SV *rouse_cb;
265
266 /* async_pool */
267 SV *saved_deffh;
268
269 /* linked list */
270 struct coro *next, *prev;
42}; 271};
43 272
44typedef struct coro *Coro__State; 273typedef struct coro *Coro__State;
45typedef struct coro *Coro__State_or_hashref; 274typedef struct coro *Coro__State_or_hashref;
46 275
47static HV *padlist_cache; 276/* the following variables are effectively part of the perl context */
277/* and get copied between struct coro and these variables */
278/* the mainr easonw e don't support windows process emulation */
279static struct CoroSLF slf_frame; /* the current slf frame */
48 280
49/* mostly copied from op.c:cv_clone2 */ 281/** Coro ********************************************************************/
50STATIC AV * 282
51clone_padlist (AV *protopadlist) 283#define PRIO_MAX 3
284#define PRIO_HIGH 1
285#define PRIO_NORMAL 0
286#define PRIO_LOW -1
287#define PRIO_IDLE -3
288#define PRIO_MIN -4
289
290/* for Coro.pm */
291static SV *coro_current;
292static SV *coro_readyhook;
293static AV *coro_ready [PRIO_MAX - PRIO_MIN + 1];
294static struct coro *coro_first;
295#define coro_nready coroapi.nready
296
297/** lowlevel stuff **********************************************************/
298
299static SV *
300coro_get_sv (pTHX_ const char *name, int create)
52{ 301{
53 AV *av; 302#if PERL_VERSION_ATLEAST (5,10,0)
54 I32 ix; 303 /* silence stupid and wrong 5.10 warning that I am unable to switch off */
55 AV *protopad_name = (AV *) * av_fetch (protopadlist, 0, FALSE); 304 get_sv (name, create);
56 AV *protopad = (AV *) * av_fetch (protopadlist, 1, FALSE); 305#endif
57 SV **pname = AvARRAY (protopad_name); 306 return get_sv (name, create);
58 SV **ppad = AvARRAY (protopad); 307}
59 I32 fname = AvFILLp (protopad_name); 308
60 I32 fpad = AvFILLp (protopad); 309static AV *
310coro_get_av (pTHX_ const char *name, int create)
311{
312#if PERL_VERSION_ATLEAST (5,10,0)
313 /* silence stupid and wrong 5.10 warning that I am unable to switch off */
314 get_av (name, create);
315#endif
316 return get_av (name, create);
317}
318
319static HV *
320coro_get_hv (pTHX_ const char *name, int create)
321{
322#if PERL_VERSION_ATLEAST (5,10,0)
323 /* silence stupid and wrong 5.10 warning that I am unable to switch off */
324 get_hv (name, create);
325#endif
326 return get_hv (name, create);
327}
328
329/* may croak */
330INLINE CV *
331coro_sv_2cv (SV *sv)
332{
333 HV *st;
334 GV *gvp;
335 return sv_2cv (sv, &st, &gvp, 0);
336}
337
338static AV *
339coro_clone_padlist (pTHX_ CV *cv)
340{
341 AV *padlist = CvPADLIST (cv);
61 AV *newpadlist, *newpad_name, *newpad; 342 AV *newpadlist, *newpad;
62 SV **npad;
63
64 newpad_name = newAV ();
65 for (ix = fname; ix >= 0; ix--)
66 av_store (newpad_name, ix, SvREFCNT_inc (pname[ix]));
67
68 newpad = newAV ();
69 av_fill (newpad, AvFILLp (protopad));
70 npad = AvARRAY (newpad);
71 343
72 newpadlist = newAV (); 344 newpadlist = newAV ();
73 AvREAL_off (newpadlist); 345 AvREAL_off (newpadlist);
74 av_store (newpadlist, 0, (SV *) newpad_name); 346#if PERL_VERSION_ATLEAST (5,10,0)
347 Perl_pad_push (aTHX_ padlist, AvFILLp (padlist) + 1);
348#else
349 Perl_pad_push (aTHX_ padlist, AvFILLp (padlist) + 1, 1);
350#endif
351 newpad = (AV *)AvARRAY (padlist)[AvFILLp (padlist)];
352 --AvFILLp (padlist);
353
354 av_store (newpadlist, 0, SvREFCNT_inc_NN (*av_fetch (padlist, 0, FALSE)));
75 av_store (newpadlist, 1, (SV *) newpad); 355 av_store (newpadlist, 1, (SV *)newpad);
76 356
77 av = newAV (); /* will be @_ */ 357 return newpadlist;
78 av_extend (av, 0); 358}
79 av_store (newpad, 0, (SV *) av);
80 AvFLAGS (av) = AVf_REIFY;
81 359
82 for (ix = fpad; ix > 0; ix--) 360static void
361free_padlist (pTHX_ AV *padlist)
362{
363 /* may be during global destruction */
364 if (SvREFCNT (padlist))
83 { 365 {
84 SV *namesv = (ix <= fname) ? pname[ix] : Nullsv; 366 I32 i = AvFILLp (padlist);
85 if (namesv && namesv != &PL_sv_undef) 367 while (i >= 0)
86 { 368 {
87 char *name = SvPVX (namesv); /* XXX */ 369 SV **svp = av_fetch (padlist, i--, FALSE);
88 if (SvFLAGS (namesv) & SVf_FAKE || *name == '&') 370 if (svp)
89 { /* lexical from outside? */
90 npad[ix] = SvREFCNT_inc (ppad[ix]);
91 } 371 {
92 else
93 { /* our own lexical */
94 SV *sv; 372 SV *sv;
95 if (*name == '&') 373 while (&PL_sv_undef != (sv = av_pop ((AV *)*svp)))
96 sv = SvREFCNT_inc (ppad[ix]); 374 SvREFCNT_dec (sv);
97 else if (*name == '@') 375
98 sv = (SV *) newAV (); 376 SvREFCNT_dec (*svp);
99 else if (*name == '%')
100 sv = (SV *) newHV ();
101 else
102 sv = NEWSV (0, 0);
103 if (!SvPADBUSY (sv))
104 SvPADMY_on (sv);
105 npad[ix] = sv;
106 } 377 }
107 } 378 }
108 else if (IS_PADGV (ppad[ix]) || IS_PADCONST (ppad[ix]))
109 {
110 npad[ix] = SvREFCNT_inc (ppad[ix]);
111 }
112 else
113 {
114 SV *sv = NEWSV (0, 0);
115 SvPADTMP_on (sv);
116 npad[ix] = sv;
117 }
118 }
119 379
120#if 0 /* NONOTUNDERSTOOD */
121 /* Now that vars are all in place, clone nested closures. */
122
123 for (ix = fpad; ix > 0; ix--) {
124 SV* namesv = (ix <= fname) ? pname[ix] : Nullsv;
125 if (namesv
126 && namesv != &PL_sv_undef
127 && !(SvFLAGS(namesv) & SVf_FAKE)
128 && *SvPVX(namesv) == '&'
129 && CvCLONE(ppad[ix]))
130 {
131 CV *kid = cv_clone((CV*)ppad[ix]);
132 SvREFCNT_dec(ppad[ix]);
133 CvCLONE_on(kid);
134 SvPADMY_on(kid);
135 npad[ix] = (SV*)kid;
136 }
137 }
138#endif
139
140 return newpadlist;
141}
142
143STATIC AV *
144free_padlist (AV *padlist)
145{
146 /* may be during global destruction */
147 if (SvREFCNT(padlist))
148 {
149 I32 i = AvFILLp(padlist);
150 while (i >= 0)
151 {
152 SV **svp = av_fetch(padlist, i--, FALSE);
153 SV *sv = svp ? *svp : Nullsv;
154 if (sv)
155 SvREFCNT_dec(sv);
156 }
157
158 SvREFCNT_dec((SV*)padlist); 380 SvREFCNT_dec ((SV*)padlist);
381 }
382}
383
384static int
385coro_cv_free (pTHX_ SV *sv, MAGIC *mg)
386{
387 AV *padlist;
388 AV *av = (AV *)mg->mg_obj;
389
390 /* casting is fun. */
391 while (&PL_sv_undef != (SV *)(padlist = (AV *)av_pop (av)))
392 free_padlist (aTHX_ padlist);
393
394 SvREFCNT_dec (av); /* sv_magicext increased the refcount */
395
396 return 0;
397}
398
399#define CORO_MAGIC_type_cv 26
400#define CORO_MAGIC_type_state PERL_MAGIC_ext
401
402static MGVTBL coro_cv_vtbl = {
403 0, 0, 0, 0,
404 coro_cv_free
405};
406
407#define CORO_MAGIC_NN(sv, type) \
408 (expect_true (SvMAGIC (sv)->mg_type == type) \
409 ? SvMAGIC (sv) \
410 : mg_find (sv, type))
411
412#define CORO_MAGIC(sv, type) \
413 (expect_true (SvMAGIC (sv)) \
414 ? CORO_MAGIC_NN (sv, type) \
415 : 0)
416
417#define CORO_MAGIC_cv(cv) CORO_MAGIC (((SV *)(cv)), CORO_MAGIC_type_cv)
418#define CORO_MAGIC_state(sv) CORO_MAGIC_NN (((SV *)(sv)), CORO_MAGIC_type_state)
419
420INLINE struct coro *
421SvSTATE_ (pTHX_ SV *coro)
422{
423 HV *stash;
424 MAGIC *mg;
425
426 if (SvROK (coro))
427 coro = SvRV (coro);
428
429 if (expect_false (SvTYPE (coro) != SVt_PVHV))
430 croak ("Coro::State object required");
431
432 stash = SvSTASH (coro);
433 if (expect_false (stash != coro_stash && stash != coro_state_stash))
434 {
435 /* very slow, but rare, check */
436 if (!sv_derived_from (sv_2mortal (newRV_inc (coro)), "Coro::State"))
437 croak ("Coro::State object required");
438 }
439
440 mg = CORO_MAGIC_state (coro);
441 return (struct coro *)mg->mg_ptr;
442}
443
444#define SvSTATE(sv) SvSTATE_ (aTHX_ (sv))
445
446/* faster than SvSTATE, but expects a coroutine hv */
447#define SvSTATE_hv(hv) ((struct coro *)CORO_MAGIC_NN ((SV *)hv, CORO_MAGIC_type_state)->mg_ptr)
448#define SvSTATE_current SvSTATE_hv (SvRV (coro_current))
449
450/* the next two functions merely cache the padlists */
451static void
452get_padlist (pTHX_ CV *cv)
453{
454 MAGIC *mg = CORO_MAGIC_cv (cv);
455 AV *av;
456
457 if (expect_true (mg && AvFILLp ((av = (AV *)mg->mg_obj)) >= 0))
458 CvPADLIST (cv) = (AV *)AvARRAY (av)[AvFILLp (av)--];
459 else
460 {
461#if CORO_PREFER_PERL_FUNCTIONS
462 /* this is probably cleaner? but also slower! */
463 /* in practise, it seems to be less stable */
464 CV *cp = Perl_cv_clone (aTHX_ cv);
465 CvPADLIST (cv) = CvPADLIST (cp);
466 CvPADLIST (cp) = 0;
467 SvREFCNT_dec (cp);
468#else
469 CvPADLIST (cv) = coro_clone_padlist (aTHX_ cv);
470#endif
471 }
472}
473
474static void
475put_padlist (pTHX_ CV *cv)
476{
477 MAGIC *mg = CORO_MAGIC_cv (cv);
478 AV *av;
479
480 if (expect_false (!mg))
481 mg = sv_magicext ((SV *)cv, (SV *)newAV (), CORO_MAGIC_type_cv, &coro_cv_vtbl, 0, 0);
482
483 av = (AV *)mg->mg_obj;
484
485 if (expect_false (AvFILLp (av) >= AvMAX (av)))
486 av_extend (av, AvMAX (av) + 1);
487
488 AvARRAY (av)[++AvFILLp (av)] = (SV *)CvPADLIST (cv);
489}
490
491/** load & save, init *******************************************************/
492
493static void
494load_perl (pTHX_ Coro__State c)
495{
496 perl_slots *slot = c->slot;
497 c->slot = 0;
498
499 PL_mainstack = c->mainstack;
500
501 GvSV (PL_defgv) = slot->defsv;
502 GvAV (PL_defgv) = slot->defav;
503 GvSV (PL_errgv) = slot->errsv;
504 GvSV (irsgv) = slot->irsgv;
505
506 #define VAR(name,type) PL_ ## name = slot->name;
507 # include "state.h"
508 #undef VAR
509
510 {
511 dSP;
512
513 CV *cv;
514
515 /* now do the ugly restore mess */
516 while (expect_true (cv = (CV *)POPs))
517 {
518 put_padlist (aTHX_ cv); /* mark this padlist as available */
519 CvDEPTH (cv) = PTR2IV (POPs);
520 CvPADLIST (cv) = (AV *)POPs;
521 }
522
523 PUTBACK;
159 } 524 }
160}
161 525
162/* the next tow functions merely cache the padlists */ 526 slf_frame = c->slf_frame;
163STATIC void 527 CORO_THROW = c->except;
164get_padlist (CV *cv)
165{
166 SV **he = hv_fetch (padlist_cache, (void *)&cv, sizeof (CV *), 0);
167
168 if (he && AvFILLp ((AV *)*he) >= 0)
169 CvPADLIST (cv) = (AV *)av_pop ((AV *)*he);
170 else
171 CvPADLIST (cv) = clone_padlist (CvPADLIST (cv));
172} 528}
173 529
174STATIC void
175put_padlist (CV *cv)
176{
177 SV **he = hv_fetch (padlist_cache, (void *)&cv, sizeof (CV *), 1);
178
179 if (SvTYPE (*he) != SVt_PVAV)
180 {
181 SvREFCNT_dec (*he);
182 *he = (SV *)newAV ();
183 }
184
185 av_push ((AV *)*he, (SV *)CvPADLIST (cv));
186}
187
188static void 530static void
189SAVE(pTHX_ Coro__State c) 531save_perl (pTHX_ Coro__State c)
190{ 532{
533 c->except = CORO_THROW;
534 c->slf_frame = slf_frame;
535
191 { 536 {
192 dSP; 537 dSP;
193 I32 cxix = cxstack_ix; 538 I32 cxix = cxstack_ix;
539 PERL_CONTEXT *ccstk = cxstack;
194 PERL_SI *top_si = PL_curstackinfo; 540 PERL_SI *top_si = PL_curstackinfo;
195 PERL_CONTEXT *ccstk = cxstack;
196 541
197 /* 542 /*
198 * the worst thing you can imagine happens first - we have to save 543 * the worst thing you can imagine happens first - we have to save
199 * (and reinitialize) all cv's in the whole callchain :( 544 * (and reinitialize) all cv's in the whole callchain :(
200 */ 545 */
201 546
202 PUSHs (Nullsv); 547 XPUSHs (Nullsv);
203 /* this loop was inspired by pp_caller */ 548 /* this loop was inspired by pp_caller */
204 for (;;) 549 for (;;)
205 { 550 {
206 while (cxix >= 0) 551 while (expect_true (cxix >= 0))
207 { 552 {
208 PERL_CONTEXT *cx = &ccstk[cxix--]; 553 PERL_CONTEXT *cx = &ccstk[cxix--];
209 554
210 if (CxTYPE(cx) == CXt_SUB) 555 if (expect_true (CxTYPE (cx) == CXt_SUB || CxTYPE (cx) == CXt_FORMAT))
211 { 556 {
212 CV *cv = cx->blk_sub.cv; 557 CV *cv = cx->blk_sub.cv;
558
213 if (CvDEPTH(cv)) 559 if (expect_true (CvDEPTH (cv)))
214 { 560 {
215#ifdef USE_THREADS
216 XPUSHs ((SV *)CvOWNER(cv));
217#endif
218 EXTEND (SP, 3); 561 EXTEND (SP, 3);
219 PUSHs ((SV *)CvDEPTH(cv));
220 PUSHs ((SV *)CvPADLIST(cv)); 562 PUSHs ((SV *)CvPADLIST (cv));
563 PUSHs (INT2PTR (SV *, (IV)CvDEPTH (cv)));
221 PUSHs ((SV *)cv); 564 PUSHs ((SV *)cv);
222 565
223 get_padlist (cv);
224
225 CvDEPTH(cv) = 0; 566 CvDEPTH (cv) = 0;
226#ifdef USE_THREADS 567 get_padlist (aTHX_ cv);
227 CvOWNER(cv) = 0;
228 error must unlock this cv etc.. etc...
229 if you are here wondering about this error message then
230 the reason is that it will not work as advertised yet
231#endif
232 } 568 }
233 } 569 }
234 else if (CxTYPE(cx) == CXt_FORMAT) 570 }
571
572 if (expect_true (top_si->si_type == PERLSI_MAIN))
573 break;
574
575 top_si = top_si->si_prev;
576 ccstk = top_si->si_cxstack;
577 cxix = top_si->si_cxix;
578 }
579
580 PUTBACK;
581 }
582
583 /* allocate some space on the context stack for our purposes */
584 /* we manually unroll here, as usually 2 slots is enough */
585 if (SLOT_COUNT >= 1) CXINC;
586 if (SLOT_COUNT >= 2) CXINC;
587 if (SLOT_COUNT >= 3) CXINC;
588 {
589 int i;
590 for (i = 3; i < SLOT_COUNT; ++i)
591 CXINC;
592 }
593 cxstack_ix -= SLOT_COUNT; /* undo allocation */
594
595 c->mainstack = PL_mainstack;
596
597 {
598 perl_slots *slot = c->slot = (perl_slots *)(cxstack + cxstack_ix + 1);
599
600 slot->defav = GvAV (PL_defgv);
601 slot->defsv = DEFSV;
602 slot->errsv = ERRSV;
603 slot->irsgv = GvSV (irsgv);
604
605 #define VAR(name,type) slot->name = PL_ ## name;
606 # include "state.h"
607 #undef VAR
608 }
609}
610
611/*
612 * allocate various perl stacks. This is almost an exact copy
613 * of perl.c:init_stacks, except that it uses less memory
614 * on the (sometimes correct) assumption that coroutines do
615 * not usually need a lot of stackspace.
616 */
617#if CORO_PREFER_PERL_FUNCTIONS
618# define coro_init_stacks(thx) init_stacks ()
619#else
620static void
621coro_init_stacks (pTHX)
622{
623 PL_curstackinfo = new_stackinfo(32, 8);
624 PL_curstackinfo->si_type = PERLSI_MAIN;
625 PL_curstack = PL_curstackinfo->si_stack;
626 PL_mainstack = PL_curstack; /* remember in case we switch stacks */
627
628 PL_stack_base = AvARRAY(PL_curstack);
629 PL_stack_sp = PL_stack_base;
630 PL_stack_max = PL_stack_base + AvMAX(PL_curstack);
631
632 New(50,PL_tmps_stack,32,SV*);
633 PL_tmps_floor = -1;
634 PL_tmps_ix = -1;
635 PL_tmps_max = 32;
636
637 New(54,PL_markstack,16,I32);
638 PL_markstack_ptr = PL_markstack;
639 PL_markstack_max = PL_markstack + 16;
640
641#ifdef SET_MARK_OFFSET
642 SET_MARK_OFFSET;
643#endif
644
645 New(54,PL_scopestack,8,I32);
646 PL_scopestack_ix = 0;
647 PL_scopestack_max = 8;
648
649 New(54,PL_savestack,24,ANY);
650 PL_savestack_ix = 0;
651 PL_savestack_max = 24;
652
653#if !PERL_VERSION_ATLEAST (5,10,0)
654 New(54,PL_retstack,4,OP*);
655 PL_retstack_ix = 0;
656 PL_retstack_max = 4;
657#endif
658}
659#endif
660
661/*
662 * destroy the stacks, the callchain etc...
663 */
664static void
665coro_destruct_stacks (pTHX)
666{
667 while (PL_curstackinfo->si_next)
668 PL_curstackinfo = PL_curstackinfo->si_next;
669
670 while (PL_curstackinfo)
671 {
672 PERL_SI *p = PL_curstackinfo->si_prev;
673
674 if (!IN_DESTRUCT)
675 SvREFCNT_dec (PL_curstackinfo->si_stack);
676
677 Safefree (PL_curstackinfo->si_cxstack);
678 Safefree (PL_curstackinfo);
679 PL_curstackinfo = p;
680 }
681
682 Safefree (PL_tmps_stack);
683 Safefree (PL_markstack);
684 Safefree (PL_scopestack);
685 Safefree (PL_savestack);
686#if !PERL_VERSION_ATLEAST (5,10,0)
687 Safefree (PL_retstack);
688#endif
689}
690
691static size_t
692coro_rss (pTHX_ struct coro *coro)
693{
694 size_t rss = sizeof (*coro);
695
696 if (coro->mainstack)
697 {
698 perl_slots tmp_slot;
699 perl_slots *slot;
700
701 if (coro->flags & CF_RUNNING)
702 {
703 slot = &tmp_slot;
704
705 #define VAR(name,type) slot->name = PL_ ## name;
706 # include "state.h"
707 #undef VAR
708 }
709 else
710 slot = coro->slot;
711
712 if (slot)
713 {
714 rss += sizeof (slot->curstackinfo);
715 rss += (slot->curstackinfo->si_cxmax + 1) * sizeof (PERL_CONTEXT);
716 rss += sizeof (SV) + sizeof (struct xpvav) + (1 + AvMAX (slot->curstack)) * sizeof (SV *);
717 rss += slot->tmps_max * sizeof (SV *);
718 rss += (slot->markstack_max - slot->markstack_ptr) * sizeof (I32);
719 rss += slot->scopestack_max * sizeof (I32);
720 rss += slot->savestack_max * sizeof (ANY);
721
722#if !PERL_VERSION_ATLEAST (5,10,0)
723 rss += slot->retstack_max * sizeof (OP *);
724#endif
725 }
726 }
727
728 return rss;
729}
730
731/** coroutine stack handling ************************************************/
732
733static int (*orig_sigelem_get) (pTHX_ SV *sv, MAGIC *mg);
734static int (*orig_sigelem_set) (pTHX_ SV *sv, MAGIC *mg);
735static int (*orig_sigelem_clr) (pTHX_ SV *sv, MAGIC *mg);
736
737/* apparently < 5.8.8 */
738#ifndef MgPV_nolen_const
739#define MgPV_nolen_const(mg) (((((int)(mg)->mg_len)) == HEf_SVKEY) ? \
740 SvPV_nolen((SV*)((mg)->mg_ptr)) : \
741 (const char*)(mg)->mg_ptr)
742#endif
743
744/*
745 * This overrides the default magic get method of %SIG elements.
746 * The original one doesn't provide for reading back of PL_diehook/PL_warnhook
747 * and instead of tryign to save and restore the hash elements, we just provide
748 * readback here.
749 * We only do this when the hook is != 0, as they are often set to 0 temporarily,
750 * not expecting this to actually change the hook. This is a potential problem
751 * when a schedule happens then, but we ignore this.
752 */
753static int
754coro_sigelem_get (pTHX_ SV *sv, MAGIC *mg)
755{
756 const char *s = MgPV_nolen_const (mg);
757
758 if (*s == '_')
759 {
760 SV **svp = 0;
761
762 if (strEQ (s, "__DIE__" )) svp = &PL_diehook;
763 if (strEQ (s, "__WARN__")) svp = &PL_warnhook;
764
765 if (svp)
766 {
767 sv_setsv (sv, *svp ? *svp : &PL_sv_undef);
768 return 0;
769 }
770 }
771
772 return orig_sigelem_get ? orig_sigelem_get (aTHX_ sv, mg) : 0;
773}
774
775static int
776coro_sigelem_clr (pTHX_ SV *sv, MAGIC *mg)
777{
778 const char *s = MgPV_nolen_const (mg);
779
780 if (*s == '_')
781 {
782 SV **svp = 0;
783
784 if (strEQ (s, "__DIE__" )) svp = &PL_diehook;
785 if (strEQ (s, "__WARN__")) svp = &PL_warnhook;
786
787 if (svp)
788 {
789 SV *old = *svp;
790 *svp = 0;
791 SvREFCNT_dec (old);
792 return 0;
793 }
794 }
795
796 return orig_sigelem_clr ? orig_sigelem_clr (aTHX_ sv, mg) : 0;
797}
798
799static int
800coro_sigelem_set (pTHX_ SV *sv, MAGIC *mg)
801{
802 const char *s = MgPV_nolen_const (mg);
803
804 if (*s == '_')
805 {
806 SV **svp = 0;
807
808 if (strEQ (s, "__DIE__" )) svp = &PL_diehook;
809 if (strEQ (s, "__WARN__")) svp = &PL_warnhook;
810
811 if (svp)
812 {
813 SV *old = *svp;
814 *svp = newSVsv (sv);
815 SvREFCNT_dec (old);
816 return 0;
817 }
818 }
819
820 return orig_sigelem_set ? orig_sigelem_set (aTHX_ sv, mg) : 0;
821}
822
823static void
824prepare_nop (pTHX_ struct coro_transfer_args *ta)
825{
826 /* kind of mega-hacky, but works */
827 ta->next = ta->prev = (struct coro *)ta;
828}
829
830static int
831slf_check_nop (pTHX_ struct CoroSLF *frame)
832{
833 return 0;
834}
835
836static UNOP coro_setup_op;
837
838static void NOINLINE /* noinline to keep it out of the transfer fast path */
839coro_setup (pTHX_ struct coro *coro)
840{
841 /*
842 * emulate part of the perl startup here.
843 */
844 coro_init_stacks (aTHX);
845
846 PL_runops = RUNOPS_DEFAULT;
847 PL_curcop = &PL_compiling;
848 PL_in_eval = EVAL_NULL;
849 PL_comppad = 0;
850 PL_curpm = 0;
851 PL_curpad = 0;
852 PL_localizing = 0;
853 PL_dirty = 0;
854 PL_restartop = 0;
855#if PERL_VERSION_ATLEAST (5,10,0)
856 PL_parser = 0;
857#endif
858
859 /* recreate the die/warn hooks */
860 PL_diehook = 0; SvSetMagicSV (*hv_fetch (hv_sig, "__DIE__" , sizeof ("__DIE__" ) - 1, 1), rv_diehook );
861 PL_warnhook = 0; SvSetMagicSV (*hv_fetch (hv_sig, "__WARN__", sizeof ("__WARN__") - 1, 1), rv_warnhook);
862
863 GvSV (PL_defgv) = newSV (0);
864 GvAV (PL_defgv) = coro->args; coro->args = 0;
865 GvSV (PL_errgv) = newSV (0);
866 GvSV (irsgv) = newSVpvn ("\n", 1); sv_magic (GvSV (irsgv), (SV *)irsgv, PERL_MAGIC_sv, "/", 0);
867 PL_rs = newSVsv (GvSV (irsgv));
868 PL_defoutgv = (GV *)SvREFCNT_inc_NN (stdoutgv);
869
870 {
871 dSP;
872 UNOP myop;
873
874 Zero (&myop, 1, UNOP);
875 myop.op_next = Nullop;
876 myop.op_flags = OPf_WANT_VOID;
877
878 PUSHMARK (SP);
879 XPUSHs (sv_2mortal (av_shift (GvAV (PL_defgv))));
880 PUTBACK;
881 PL_op = (OP *)&myop;
882 PL_op = PL_ppaddr[OP_ENTERSUB](aTHX);
883 SPAGAIN;
884 }
885
886 /* this newly created coroutine might be run on an existing cctx which most
887 * likely was suspended in pp_slf, so we have to emulate entering pp_slf here.
888 */
889 slf_frame.prepare = prepare_nop; /* provide a nop function for an eventual pp_slf */
890 slf_frame.check = slf_check_nop; /* signal pp_slf to not repeat */
891
892 /* and we have to provide the pp_slf op in any case, so pp_slf can skip it */
893 coro_setup_op.op_next = PL_op;
894 coro_setup_op.op_type = OP_CUSTOM;
895 coro_setup_op.op_ppaddr = pp_slf;
896 /* no flags required, as an init function won't be called */
897
898 PL_op = (OP *)&coro_setup_op;
899
900 /* copy throw, in case it was set before coro_setup */
901 CORO_THROW = coro->except;
902}
903
904static void
905coro_destruct (pTHX_ struct coro *coro)
906{
907 if (!IN_DESTRUCT)
908 {
909 /* restore all saved variables and stuff */
910 LEAVE_SCOPE (0);
911 assert (PL_tmps_floor == -1);
912
913 /* free all temporaries */
914 FREETMPS;
915 assert (PL_tmps_ix == -1);
916
917 /* unwind all extra stacks */
918 POPSTACK_TO (PL_mainstack);
919
920 /* unwind main stack */
921 dounwind (-1);
922 }
923
924 SvREFCNT_dec (GvSV (PL_defgv));
925 SvREFCNT_dec (GvAV (PL_defgv));
926 SvREFCNT_dec (GvSV (PL_errgv));
927 SvREFCNT_dec (PL_defoutgv);
928 SvREFCNT_dec (PL_rs);
929 SvREFCNT_dec (GvSV (irsgv));
930
931 SvREFCNT_dec (PL_diehook);
932 SvREFCNT_dec (PL_warnhook);
933
934 SvREFCNT_dec (CORO_THROW);
935 SvREFCNT_dec (coro->saved_deffh);
936 SvREFCNT_dec (coro->rouse_cb);
937
938 coro_destruct_stacks (aTHX);
939}
940
941INLINE void
942free_coro_mortal (pTHX)
943{
944 if (expect_true (coro_mortal))
945 {
946 SvREFCNT_dec (coro_mortal);
947 coro_mortal = 0;
948 }
949}
950
951static int
952runops_trace (pTHX)
953{
954 COP *oldcop = 0;
955 int oldcxix = -2;
956 struct coro *coro = SvSTATE_current; /* trace cctx is tied to specific coro */
957 coro_cctx *cctx = coro->cctx;
958
959 while ((PL_op = CALL_FPTR (PL_op->op_ppaddr) (aTHX)))
960 {
961 PERL_ASYNC_CHECK ();
962
963 if (cctx->flags & CC_TRACE_ALL)
964 {
965 if (PL_op->op_type == OP_LEAVESUB && cctx->flags & CC_TRACE_SUB)
966 {
967 PERL_CONTEXT *cx = &cxstack[cxstack_ix];
968 SV **bot, **top;
969 AV *av = newAV (); /* return values */
970 SV **cb;
971 dSP;
972
973 GV *gv = CvGV (cx->blk_sub.cv);
974 SV *fullname = sv_2mortal (newSV (0));
975 if (isGV (gv))
976 gv_efullname3 (fullname, gv, 0);
977
978 bot = PL_stack_base + cx->blk_oldsp + 1;
979 top = cx->blk_gimme == G_ARRAY ? SP + 1
980 : cx->blk_gimme == G_SCALAR ? bot + 1
981 : bot;
982
983 av_extend (av, top - bot);
984 while (bot < top)
985 av_push (av, SvREFCNT_inc_NN (*bot++));
986
987 PL_runops = RUNOPS_DEFAULT;
988 ENTER;
989 SAVETMPS;
990 EXTEND (SP, 3);
991 PUSHMARK (SP);
992 PUSHs (&PL_sv_no);
993 PUSHs (fullname);
994 PUSHs (sv_2mortal (newRV_noinc ((SV *)av)));
995 PUTBACK;
996 cb = hv_fetch ((HV *)SvRV (coro_current), "_trace_sub_cb", sizeof ("_trace_sub_cb") - 1, 0);
997 if (cb) call_sv (*cb, G_KEEPERR | G_EVAL | G_VOID | G_DISCARD);
998 SPAGAIN;
999 FREETMPS;
1000 LEAVE;
1001 PL_runops = runops_trace;
1002 }
1003
1004 if (oldcop != PL_curcop)
1005 {
1006 oldcop = PL_curcop;
1007
1008 if (PL_curcop != &PL_compiling)
1009 {
1010 SV **cb;
1011
1012 if (oldcxix != cxstack_ix && cctx->flags & CC_TRACE_SUB)
1013 {
1014 PERL_CONTEXT *cx = &cxstack[cxstack_ix];
1015
1016 if (CxTYPE (cx) == CXt_SUB && oldcxix < cxstack_ix)
1017 {
1018 runops_proc_t old_runops = PL_runops;
1019 dSP;
1020 GV *gv = CvGV (cx->blk_sub.cv);
1021 SV *fullname = sv_2mortal (newSV (0));
1022
1023 if (isGV (gv))
1024 gv_efullname3 (fullname, gv, 0);
1025
1026 PL_runops = RUNOPS_DEFAULT;
1027 ENTER;
1028 SAVETMPS;
1029 EXTEND (SP, 3);
1030 PUSHMARK (SP);
1031 PUSHs (&PL_sv_yes);
1032 PUSHs (fullname);
1033 PUSHs (CxHASARGS (cx) ? sv_2mortal (newRV_inc ((SV *)cx->blk_sub.argarray)) : &PL_sv_undef);
1034 PUTBACK;
1035 cb = hv_fetch ((HV *)SvRV (coro_current), "_trace_sub_cb", sizeof ("_trace_sub_cb") - 1, 0);
1036 if (cb) call_sv (*cb, G_KEEPERR | G_EVAL | G_VOID | G_DISCARD);
1037 SPAGAIN;
1038 FREETMPS;
1039 LEAVE;
1040 PL_runops = runops_trace;
1041 }
1042
1043 oldcxix = cxstack_ix;
1044 }
1045
1046 if (cctx->flags & CC_TRACE_LINE)
1047 {
1048 dSP;
1049
1050 PL_runops = RUNOPS_DEFAULT;
1051 ENTER;
1052 SAVETMPS;
1053 EXTEND (SP, 3);
1054 PL_runops = RUNOPS_DEFAULT;
1055 PUSHMARK (SP);
1056 PUSHs (sv_2mortal (newSVpv (OutCopFILE (oldcop), 0)));
1057 PUSHs (sv_2mortal (newSViv (CopLINE (oldcop))));
1058 PUTBACK;
1059 cb = hv_fetch ((HV *)SvRV (coro_current), "_trace_line_cb", sizeof ("_trace_line_cb") - 1, 0);
1060 if (cb) call_sv (*cb, G_KEEPERR | G_EVAL | G_VOID | G_DISCARD);
1061 SPAGAIN;
1062 FREETMPS;
1063 LEAVE;
1064 PL_runops = runops_trace;
1065 }
1066 }
1067 }
1068 }
1069 }
1070
1071 TAINT_NOT;
1072 return 0;
1073}
1074
1075static struct coro_cctx *cctx_ssl_cctx;
1076static struct CoroSLF cctx_ssl_frame;
1077
1078static void
1079slf_prepare_set_stacklevel (pTHX_ struct coro_transfer_args *ta)
1080{
1081 ta->prev = (struct coro *)cctx_ssl_cctx;
1082 ta->next = 0;
1083}
1084
1085static int
1086slf_check_set_stacklevel (pTHX_ struct CoroSLF *frame)
1087{
1088 *frame = cctx_ssl_frame;
1089
1090 return frame->check (aTHX_ frame); /* execute the restored frame - there must be one */
1091}
1092
1093/* initialises PL_top_env and injects a pseudo-slf-call to set the stacklevel */
1094static void NOINLINE
1095cctx_prepare (pTHX_ coro_cctx *cctx)
1096{
1097 PL_top_env = &PL_start_env;
1098
1099 if (cctx->flags & CC_TRACE)
1100 PL_runops = runops_trace;
1101
1102 /* we already must be executing an SLF op, there is no other valid way
1103 * that can lead to creation of a new cctx */
1104 assert (("FATAL: can't prepare slf-less cctx in Coro module (please report)",
1105 slf_frame.prepare && PL_op->op_ppaddr == pp_slf));
1106
1107 /* we must emulate leaving pp_slf, which is done inside slf_check_set_stacklevel */
1108 cctx_ssl_cctx = cctx;
1109 cctx_ssl_frame = slf_frame;
1110
1111 slf_frame.prepare = slf_prepare_set_stacklevel;
1112 slf_frame.check = slf_check_set_stacklevel;
1113}
1114
1115/* the tail of transfer: execute stuff we can only do after a transfer */
1116INLINE void
1117transfer_tail (pTHX)
1118{
1119 free_coro_mortal (aTHX);
1120}
1121
1122/*
1123 * this is a _very_ stripped down perl interpreter ;)
1124 */
1125static void
1126cctx_run (void *arg)
1127{
1128#ifdef USE_ITHREADS
1129# if CORO_PTHREAD
1130 PERL_SET_CONTEXT (coro_thx);
1131# endif
1132#endif
1133 {
1134 dTHX;
1135
1136 /* normally we would need to skip the entersub here */
1137 /* not doing so will re-execute it, which is exactly what we want */
1138 /* PL_nop = PL_nop->op_next */
1139
1140 /* inject a fake subroutine call to cctx_init */
1141 cctx_prepare (aTHX_ (coro_cctx *)arg);
1142
1143 /* cctx_run is the alternative tail of transfer() */
1144 transfer_tail (aTHX);
1145
1146 /* somebody or something will hit me for both perl_run and PL_restartop */
1147 PL_restartop = PL_op;
1148 perl_run (PL_curinterp);
1149
1150 /*
1151 * If perl-run returns we assume exit() was being called or the coro
1152 * fell off the end, which seems to be the only valid (non-bug)
1153 * reason for perl_run to return. We try to exit by jumping to the
1154 * bootstrap-time "top" top_env, as we cannot restore the "main"
1155 * coroutine as Coro has no such concept
1156 */
1157 PL_top_env = main_top_env;
1158 JMPENV_JUMP (2); /* I do not feel well about the hardcoded 2 at all */
1159 }
1160}
1161
1162static coro_cctx *
1163cctx_new ()
1164{
1165 coro_cctx *cctx;
1166
1167 ++cctx_count;
1168 New (0, cctx, 1, coro_cctx);
1169
1170 cctx->gen = cctx_gen;
1171 cctx->flags = 0;
1172 cctx->idle_sp = 0; /* can be accessed by transfer between cctx_run and set_stacklevel, on throw */
1173
1174 return cctx;
1175}
1176
1177/* create a new cctx only suitable as source */
1178static coro_cctx *
1179cctx_new_empty ()
1180{
1181 coro_cctx *cctx = cctx_new ();
1182
1183 cctx->sptr = 0;
1184 coro_create (&cctx->cctx, 0, 0, 0, 0);
1185
1186 return cctx;
1187}
1188
1189/* create a new cctx suitable as destination/running a perl interpreter */
1190static coro_cctx *
1191cctx_new_run ()
1192{
1193 coro_cctx *cctx = cctx_new ();
1194 void *stack_start;
1195 size_t stack_size;
1196
1197#if HAVE_MMAP
1198 cctx->ssize = ((cctx_stacksize * sizeof (long) + PAGESIZE - 1) / PAGESIZE + CORO_STACKGUARD) * PAGESIZE;
1199 /* mmap supposedly does allocate-on-write for us */
1200 cctx->sptr = mmap (0, cctx->ssize, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
1201
1202 if (cctx->sptr != (void *)-1)
1203 {
1204 #if CORO_STACKGUARD
1205 mprotect (cctx->sptr, CORO_STACKGUARD * PAGESIZE, PROT_NONE);
1206 #endif
1207 stack_start = (char *)cctx->sptr + CORO_STACKGUARD * PAGESIZE;
1208 stack_size = cctx->ssize - CORO_STACKGUARD * PAGESIZE;
1209 cctx->flags |= CC_MAPPED;
1210 }
1211 else
1212#endif
1213 {
1214 cctx->ssize = cctx_stacksize * (long)sizeof (long);
1215 New (0, cctx->sptr, cctx_stacksize, long);
1216
1217 if (!cctx->sptr)
1218 {
1219 perror ("FATAL: unable to allocate stack for coroutine, exiting.");
1220 _exit (EXIT_FAILURE);
1221 }
1222
1223 stack_start = cctx->sptr;
1224 stack_size = cctx->ssize;
1225 }
1226
1227 #if CORO_USE_VALGRIND
1228 cctx->valgrind_id = VALGRIND_STACK_REGISTER ((char *)stack_start, (char *)stack_start + stack_size);
1229 #endif
1230
1231 coro_create (&cctx->cctx, cctx_run, (void *)cctx, stack_start, stack_size);
1232
1233 return cctx;
1234}
1235
1236static void
1237cctx_destroy (coro_cctx *cctx)
1238{
1239 if (!cctx)
1240 return;
1241
1242 --cctx_count;
1243 coro_destroy (&cctx->cctx);
1244
1245 /* coro_transfer creates new, empty cctx's */
1246 if (cctx->sptr)
1247 {
1248 #if CORO_USE_VALGRIND
1249 VALGRIND_STACK_DEREGISTER (cctx->valgrind_id);
1250 #endif
1251
1252#if HAVE_MMAP
1253 if (cctx->flags & CC_MAPPED)
1254 munmap (cctx->sptr, cctx->ssize);
1255 else
1256#endif
1257 Safefree (cctx->sptr);
1258 }
1259
1260 Safefree (cctx);
1261}
1262
1263/* wether this cctx should be destructed */
1264#define CCTX_EXPIRED(cctx) ((cctx)->gen != cctx_gen || ((cctx)->flags & CC_NOREUSE))
1265
1266static coro_cctx *
1267cctx_get (pTHX)
1268{
1269 while (expect_true (cctx_first))
1270 {
1271 coro_cctx *cctx = cctx_first;
1272 cctx_first = cctx->next;
1273 --cctx_idle;
1274
1275 if (expect_true (!CCTX_EXPIRED (cctx)))
1276 return cctx;
1277
1278 cctx_destroy (cctx);
1279 }
1280
1281 return cctx_new_run ();
1282}
1283
1284static void
1285cctx_put (coro_cctx *cctx)
1286{
1287 assert (("FATAL: cctx_put called on non-initialised cctx in Coro (please report)", cctx->sptr));
1288
1289 /* free another cctx if overlimit */
1290 if (expect_false (cctx_idle >= cctx_max_idle))
1291 {
1292 coro_cctx *first = cctx_first;
1293 cctx_first = first->next;
1294 --cctx_idle;
1295
1296 cctx_destroy (first);
1297 }
1298
1299 ++cctx_idle;
1300 cctx->next = cctx_first;
1301 cctx_first = cctx;
1302}
1303
1304/** coroutine switching *****************************************************/
1305
1306static void
1307transfer_check (pTHX_ struct coro *prev, struct coro *next)
1308{
1309 /* TODO: throwing up here is considered harmful */
1310
1311 if (expect_true (prev != next))
1312 {
1313 if (expect_false (!(prev->flags & (CF_RUNNING | CF_NEW))))
1314 croak ("Coro::State::transfer called with non-running/new prev Coro::State, but can only transfer from running or new states,");
1315
1316 if (expect_false (next->flags & CF_RUNNING))
1317 croak ("Coro::State::transfer called with running next Coro::State, but can only transfer to inactive states,");
1318
1319 if (expect_false (next->flags & CF_DESTROYED))
1320 croak ("Coro::State::transfer called with destroyed next Coro::State, but can only transfer to inactive states,");
1321
1322#if !PERL_VERSION_ATLEAST (5,10,0)
1323 if (expect_false (PL_lex_state != LEX_NOTPARSING))
1324 croak ("Coro::State::transfer called while parsing, but this is not supported in your perl version,");
1325#endif
1326 }
1327}
1328
1329/* always use the TRANSFER macro */
1330static void NOINLINE /* noinline so we have a fixed stackframe */
1331transfer (pTHX_ struct coro *prev, struct coro *next, int force_cctx)
1332{
1333 dSTACKLEVEL;
1334
1335 /* sometimes transfer is only called to set idle_sp */
1336 if (expect_false (!next))
1337 {
1338 ((coro_cctx *)prev)->idle_sp = STACKLEVEL;
1339 assert (((coro_cctx *)prev)->idle_te = PL_top_env); /* just for the side-effect when asserts are enabled */
1340 }
1341 else if (expect_true (prev != next))
1342 {
1343 coro_cctx *prev__cctx;
1344
1345 if (expect_false (prev->flags & CF_NEW))
1346 {
1347 /* create a new empty/source context */
1348 prev->cctx = cctx_new_empty ();
1349 prev->flags &= ~CF_NEW;
1350 prev->flags |= CF_RUNNING;
1351 }
1352
1353 prev->flags &= ~CF_RUNNING;
1354 next->flags |= CF_RUNNING;
1355
1356 /* first get rid of the old state */
1357 save_perl (aTHX_ prev);
1358
1359 if (expect_false (next->flags & CF_NEW))
1360 {
1361 /* need to start coroutine */
1362 next->flags &= ~CF_NEW;
1363 /* setup coroutine call */
1364 coro_setup (aTHX_ next);
1365 }
1366 else
1367 load_perl (aTHX_ next);
1368
1369 prev__cctx = prev->cctx;
1370
1371 /* possibly untie and reuse the cctx */
1372 if (expect_true (
1373 prev__cctx->idle_sp == STACKLEVEL
1374 && !(prev__cctx->flags & CC_TRACE)
1375 && !force_cctx
1376 ))
1377 {
1378 /* I assume that stacklevel is a stronger indicator than PL_top_env changes */
1379 assert (("FATAL: current top_env must equal previous top_env in Coro (please report)", PL_top_env == prev__cctx->idle_te));
1380
1381 prev->cctx = 0;
1382
1383 /* if the cctx is about to be destroyed we need to make sure we won't see it in cctx_get */
1384 /* without this the next cctx_get might destroy the prev__cctx while still in use */
1385 if (expect_false (CCTX_EXPIRED (prev__cctx)))
1386 if (!next->cctx)
1387 next->cctx = cctx_get (aTHX);
1388
1389 cctx_put (prev__cctx);
1390 }
1391
1392 ++next->usecount;
1393
1394 if (expect_true (!next->cctx))
1395 next->cctx = cctx_get (aTHX);
1396
1397 if (expect_false (prev__cctx != next->cctx))
1398 {
1399 prev__cctx->top_env = PL_top_env;
1400 PL_top_env = next->cctx->top_env;
1401 coro_transfer (&prev__cctx->cctx, &next->cctx->cctx);
1402 }
1403
1404 transfer_tail (aTHX);
1405 }
1406}
1407
1408#define TRANSFER(ta, force_cctx) transfer (aTHX_ (ta).prev, (ta).next, (force_cctx))
1409#define TRANSFER_CHECK(ta) transfer_check (aTHX_ (ta).prev, (ta).next)
1410
1411/** high level stuff ********************************************************/
1412
1413static int
1414coro_state_destroy (pTHX_ struct coro *coro)
1415{
1416 if (coro->flags & CF_DESTROYED)
1417 return 0;
1418
1419 if (coro->on_destroy)
1420 coro->on_destroy (aTHX_ coro);
1421
1422 coro->flags |= CF_DESTROYED;
1423
1424 if (coro->flags & CF_READY)
1425 {
1426 /* reduce nready, as destroying a ready coro effectively unreadies it */
1427 /* alternative: look through all ready queues and remove the coro */
1428 --coro_nready;
1429 }
1430 else
1431 coro->flags |= CF_READY; /* make sure it is NOT put into the readyqueue */
1432
1433 if (coro->mainstack && coro->mainstack != main_mainstack)
1434 {
1435 struct coro temp;
1436
1437 assert (("FATAL: tried to destroy currently running coroutine (please report)", !(coro->flags & CF_RUNNING)));
1438
1439 save_perl (aTHX_ &temp);
1440 load_perl (aTHX_ coro);
1441
1442 coro_destruct (aTHX_ coro);
1443
1444 load_perl (aTHX_ &temp);
1445
1446 coro->slot = 0;
1447 }
1448
1449 cctx_destroy (coro->cctx);
1450 SvREFCNT_dec (coro->startcv);
1451 SvREFCNT_dec (coro->args);
1452
1453 if (coro->next) coro->next->prev = coro->prev;
1454 if (coro->prev) coro->prev->next = coro->next;
1455 if (coro == coro_first) coro_first = coro->next;
1456
1457 return 1;
1458}
1459
1460static int
1461coro_state_free (pTHX_ SV *sv, MAGIC *mg)
1462{
1463 struct coro *coro = (struct coro *)mg->mg_ptr;
1464 mg->mg_ptr = 0;
1465
1466 coro->hv = 0;
1467
1468 if (--coro->refcnt < 0)
1469 {
1470 coro_state_destroy (aTHX_ coro);
1471 Safefree (coro);
1472 }
1473
1474 return 0;
1475}
1476
1477static int
1478coro_state_dup (pTHX_ MAGIC *mg, CLONE_PARAMS *params)
1479{
1480 struct coro *coro = (struct coro *)mg->mg_ptr;
1481
1482 ++coro->refcnt;
1483
1484 return 0;
1485}
1486
1487static MGVTBL coro_state_vtbl = {
1488 0, 0, 0, 0,
1489 coro_state_free,
1490 0,
1491#ifdef MGf_DUP
1492 coro_state_dup,
1493#else
1494# define MGf_DUP 0
1495#endif
1496};
1497
1498static void
1499prepare_transfer (pTHX_ struct coro_transfer_args *ta, SV *prev_sv, SV *next_sv)
1500{
1501 ta->prev = SvSTATE (prev_sv);
1502 ta->next = SvSTATE (next_sv);
1503 TRANSFER_CHECK (*ta);
1504}
1505
1506static void
1507api_transfer (pTHX_ SV *prev_sv, SV *next_sv)
1508{
1509 struct coro_transfer_args ta;
1510
1511 prepare_transfer (aTHX_ &ta, prev_sv, next_sv);
1512 TRANSFER (ta, 1);
1513}
1514
1515/*****************************************************************************/
1516/* gensub: simple closure generation utility */
1517
1518#define GENSUB_ARG CvXSUBANY (cv).any_ptr
1519
1520/* create a closure from XS, returns a code reference */
1521/* the arg can be accessed via GENSUB_ARG from the callback */
1522/* the callback must use dXSARGS/XSRETURN */
1523static SV *
1524gensub (pTHX_ void (*xsub)(pTHX_ CV *), void *arg)
1525{
1526 CV *cv = (CV *)newSV (0);
1527
1528 sv_upgrade ((SV *)cv, SVt_PVCV);
1529
1530 CvANON_on (cv);
1531 CvISXSUB_on (cv);
1532 CvXSUB (cv) = xsub;
1533 GENSUB_ARG = arg;
1534
1535 return newRV_noinc ((SV *)cv);
1536}
1537
1538/** Coro ********************************************************************/
1539
1540INLINE void
1541coro_enq (pTHX_ struct coro *coro)
1542{
1543 av_push (coro_ready [coro->prio - PRIO_MIN], SvREFCNT_inc_NN (coro->hv));
1544}
1545
1546INLINE SV *
1547coro_deq (pTHX)
1548{
1549 int prio;
1550
1551 for (prio = PRIO_MAX - PRIO_MIN + 1; --prio >= 0; )
1552 if (AvFILLp (coro_ready [prio]) >= 0)
1553 return av_shift (coro_ready [prio]);
1554
1555 return 0;
1556}
1557
1558static int
1559api_ready (pTHX_ SV *coro_sv)
1560{
1561 struct coro *coro;
1562 SV *sv_hook;
1563 void (*xs_hook)(void);
1564
1565 if (SvROK (coro_sv))
1566 coro_sv = SvRV (coro_sv);
1567
1568 coro = SvSTATE (coro_sv);
1569
1570 if (coro->flags & CF_READY)
1571 return 0;
1572
1573 coro->flags |= CF_READY;
1574
1575 sv_hook = coro_nready ? 0 : coro_readyhook;
1576 xs_hook = coro_nready ? 0 : coroapi.readyhook;
1577
1578 coro_enq (aTHX_ coro);
1579 ++coro_nready;
1580
1581 if (sv_hook)
1582 {
1583 dSP;
1584
1585 ENTER;
1586 SAVETMPS;
1587
1588 PUSHMARK (SP);
1589 PUTBACK;
1590 call_sv (sv_hook, G_VOID | G_DISCARD);
1591
1592 FREETMPS;
1593 LEAVE;
1594 }
1595
1596 if (xs_hook)
1597 xs_hook ();
1598
1599 return 1;
1600}
1601
1602static int
1603api_is_ready (pTHX_ SV *coro_sv)
1604{
1605 return !!(SvSTATE (coro_sv)->flags & CF_READY);
1606}
1607
1608INLINE void
1609prepare_schedule (pTHX_ struct coro_transfer_args *ta)
1610{
1611 SV *prev_sv, *next_sv;
1612
1613 for (;;)
1614 {
1615 next_sv = coro_deq (aTHX);
1616
1617 /* nothing to schedule: call the idle handler */
1618 if (expect_false (!next_sv))
1619 {
1620 dSP;
1621
1622 ENTER;
1623 SAVETMPS;
1624
1625 PUSHMARK (SP);
1626 PUTBACK;
1627 call_sv (get_sv ("Coro::idle", FALSE), G_VOID | G_DISCARD);
1628
1629 FREETMPS;
1630 LEAVE;
1631 continue;
1632 }
1633
1634 ta->next = SvSTATE_hv (next_sv);
1635
1636 /* cannot transfer to destroyed coros, skip and look for next */
1637 if (expect_false (ta->next->flags & CF_DESTROYED))
1638 {
1639 SvREFCNT_dec (next_sv);
1640 /* coro_nready has already been taken care of by destroy */
1641 continue;
1642 }
1643
1644 --coro_nready;
1645 break;
1646 }
1647
1648 /* free this only after the transfer */
1649 prev_sv = SvRV (coro_current);
1650 ta->prev = SvSTATE_hv (prev_sv);
1651 TRANSFER_CHECK (*ta);
1652 assert (("FATAL: next coroutine isn't marked as ready in Coro (please report)", ta->next->flags & CF_READY));
1653 ta->next->flags &= ~CF_READY;
1654 SvRV_set (coro_current, next_sv);
1655
1656 free_coro_mortal (aTHX);
1657 coro_mortal = prev_sv;
1658}
1659
1660INLINE void
1661prepare_cede (pTHX_ struct coro_transfer_args *ta)
1662{
1663 api_ready (aTHX_ coro_current);
1664 prepare_schedule (aTHX_ ta);
1665}
1666
1667INLINE void
1668prepare_cede_notself (pTHX_ struct coro_transfer_args *ta)
1669{
1670 SV *prev = SvRV (coro_current);
1671
1672 if (coro_nready)
1673 {
1674 prepare_schedule (aTHX_ ta);
1675 api_ready (aTHX_ prev);
1676 }
1677 else
1678 prepare_nop (aTHX_ ta);
1679}
1680
1681static void
1682api_schedule (pTHX)
1683{
1684 struct coro_transfer_args ta;
1685
1686 prepare_schedule (aTHX_ &ta);
1687 TRANSFER (ta, 1);
1688}
1689
1690static int
1691api_cede (pTHX)
1692{
1693 struct coro_transfer_args ta;
1694
1695 prepare_cede (aTHX_ &ta);
1696
1697 if (expect_true (ta.prev != ta.next))
1698 {
1699 TRANSFER (ta, 1);
1700 return 1;
1701 }
1702 else
1703 return 0;
1704}
1705
1706static int
1707api_cede_notself (pTHX)
1708{
1709 if (coro_nready)
1710 {
1711 struct coro_transfer_args ta;
1712
1713 prepare_cede_notself (aTHX_ &ta);
1714 TRANSFER (ta, 1);
1715 return 1;
1716 }
1717 else
1718 return 0;
1719}
1720
1721static void
1722api_trace (pTHX_ SV *coro_sv, int flags)
1723{
1724 struct coro *coro = SvSTATE (coro_sv);
1725
1726 if (flags & CC_TRACE)
1727 {
1728 if (!coro->cctx)
1729 coro->cctx = cctx_new_run ();
1730 else if (!(coro->cctx->flags & CC_TRACE))
1731 croak ("cannot enable tracing on coroutine with custom stack,");
1732
1733 coro->cctx->flags |= CC_NOREUSE | (flags & (CC_TRACE | CC_TRACE_ALL));
1734 }
1735 else if (coro->cctx && coro->cctx->flags & CC_TRACE)
1736 {
1737 coro->cctx->flags &= ~(CC_TRACE | CC_TRACE_ALL);
1738
1739 if (coro->flags & CF_RUNNING)
1740 PL_runops = RUNOPS_DEFAULT;
1741 else
1742 coro->slot->runops = RUNOPS_DEFAULT;
1743 }
1744}
1745
1746/*****************************************************************************/
1747/* rouse callback */
1748
1749#define CORO_MAGIC_type_rouse PERL_MAGIC_ext
1750
1751static void
1752coro_rouse_callback (pTHX_ CV *cv)
1753{
1754 dXSARGS;
1755 SV *data = (SV *)GENSUB_ARG;
1756
1757 if (SvTYPE (SvRV (data)) != SVt_PVAV)
1758 {
1759 /* first call, set args */
1760 int i;
1761 AV *av = newAV ();
1762 SV *coro = SvRV (data);
1763
1764 SvRV_set (data, (SV *)av);
1765 api_ready (aTHX_ coro);
1766 SvREFCNT_dec (coro);
1767
1768 /* better take a full copy of the arguments */
1769 while (items--)
1770 av_store (av, items, newSVsv (ST (items)));
1771 }
1772
1773 XSRETURN_EMPTY;
1774}
1775
1776static int
1777slf_check_rouse_wait (pTHX_ struct CoroSLF *frame)
1778{
1779 SV *data = (SV *)frame->data;
1780
1781 if (CORO_THROW)
1782 return 0;
1783
1784 if (SvTYPE (SvRV (data)) != SVt_PVAV)
1785 return 1;
1786
1787 /* now push all results on the stack */
1788 {
1789 dSP;
1790 AV *av = (AV *)SvRV (data);
1791 int i;
1792
1793 EXTEND (SP, AvFILLp (av) + 1);
1794 for (i = 0; i <= AvFILLp (av); ++i)
1795 PUSHs (sv_2mortal (AvARRAY (av)[i]));
1796
1797 /* we have stolen the elements, so ste length to zero and free */
1798 AvFILLp (av) = -1;
1799 av_undef (av);
1800
1801 PUTBACK;
1802 }
1803
1804 return 0;
1805}
1806
1807static void
1808slf_init_rouse_wait (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items)
1809{
1810 SV *cb;
1811
1812 if (items)
1813 cb = arg [0];
1814 else
1815 {
1816 struct coro *coro = SvSTATE_current;
1817
1818 if (!coro->rouse_cb)
1819 croak ("Coro::rouse_wait called without rouse callback, and no default rouse callback found either,");
1820
1821 cb = sv_2mortal (coro->rouse_cb);
1822 coro->rouse_cb = 0;
1823 }
1824
1825 if (!SvROK (cb)
1826 || SvTYPE (SvRV (cb)) != SVt_PVCV
1827 || CvXSUB ((CV *)SvRV (cb)) != coro_rouse_callback)
1828 croak ("Coro::rouse_wait called with illegal callback argument,");
1829
1830 {
1831 CV *cv = (CV *)SvRV (cb); /* for GENSUB_ARG */
1832 SV *data = (SV *)GENSUB_ARG;
1833
1834 frame->data = (void *)data;
1835 frame->prepare = SvTYPE (SvRV (data)) == SVt_PVAV ? prepare_nop : prepare_schedule;
1836 frame->check = slf_check_rouse_wait;
1837 }
1838}
1839
1840static SV *
1841coro_new_rouse_cb (pTHX)
1842{
1843 HV *hv = (HV *)SvRV (coro_current);
1844 struct coro *coro = SvSTATE_hv (hv);
1845 SV *data = newRV_inc ((SV *)hv);
1846 SV *cb = gensub (aTHX_ coro_rouse_callback, (void *)data);
1847
1848 sv_magicext (SvRV (cb), data, CORO_MAGIC_type_rouse, 0, 0, 0);
1849 SvREFCNT_dec (data); /* magicext increases the refcount */
1850
1851 SvREFCNT_dec (coro->rouse_cb);
1852 coro->rouse_cb = SvREFCNT_inc_NN (cb);
1853
1854 return cb;
1855}
1856
1857/*****************************************************************************/
1858/* schedule-like-function opcode (SLF) */
1859
1860static UNOP slf_restore; /* restore stack as entersub did, for first-re-run */
1861static const CV *slf_cv;
1862static SV **slf_argv;
1863static int slf_argc, slf_arga; /* count, allocated */
1864static I32 slf_ax; /* top of stack, for restore */
1865
1866/* this restores the stack in the case we patched the entersub, to */
1867/* recreate the stack frame as perl will on following calls */
1868/* since entersub cleared the stack */
1869static OP *
1870pp_restore (pTHX)
1871{
1872 int i;
1873 SV **SP = PL_stack_base + slf_ax;
1874
1875 PUSHMARK (SP);
1876
1877 EXTEND (SP, slf_argc + 1);
1878
1879 for (i = 0; i < slf_argc; ++i)
1880 PUSHs (sv_2mortal (slf_argv [i]));
1881
1882 PUSHs ((SV *)CvGV (slf_cv));
1883
1884 RETURNOP (slf_restore.op_first);
1885}
1886
1887static void
1888slf_prepare_transfer (pTHX_ struct coro_transfer_args *ta)
1889{
1890 SV **arg = (SV **)slf_frame.data;
1891
1892 prepare_transfer (aTHX_ ta, arg [0], arg [1]);
1893}
1894
1895static void
1896slf_init_transfer (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items)
1897{
1898 if (items != 2)
1899 croak ("Coro::State::transfer (prev, next) expects two arguments, not %d,", items);
1900
1901 frame->prepare = slf_prepare_transfer;
1902 frame->check = slf_check_nop;
1903 frame->data = (void *)arg; /* let's hope it will stay valid */
1904}
1905
1906static void
1907slf_init_schedule (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items)
1908{
1909 frame->prepare = prepare_schedule;
1910 frame->check = slf_check_nop;
1911}
1912
1913static void
1914slf_init_cede (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items)
1915{
1916 frame->prepare = prepare_cede;
1917 frame->check = slf_check_nop;
1918}
1919
1920static void
1921slf_init_cede_notself (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items)
1922{
1923 frame->prepare = prepare_cede_notself;
1924 frame->check = slf_check_nop;
1925}
1926
1927/*
1928 * these not obviously related functions are all rolled into one
1929 * function to increase chances that they all will call transfer with the same
1930 * stack offset
1931 * SLF stands for "schedule-like-function".
1932 */
1933static OP *
1934pp_slf (pTHX)
1935{
1936 I32 checkmark; /* mark SP to see how many elements check has pushed */
1937
1938 /* set up the slf frame, unless it has already been set-up */
1939 /* the latter happens when a new coro has been started */
1940 /* or when a new cctx was attached to an existing coroutine */
1941 if (expect_true (!slf_frame.prepare))
1942 {
1943 /* first iteration */
1944 dSP;
1945 SV **arg = PL_stack_base + TOPMARK + 1;
1946 int items = SP - arg; /* args without function object */
1947 SV *gv = *sp;
1948
1949 /* do a quick consistency check on the "function" object, and if it isn't */
1950 /* for us, divert to the real entersub */
1951 if (SvTYPE (gv) != SVt_PVGV
1952 || !GvCV (gv)
1953 || !(CvFLAGS (GvCV (gv)) & CVf_SLF))
1954 return PL_ppaddr[OP_ENTERSUB](aTHX);
1955
1956 if (!(PL_op->op_flags & OPf_STACKED))
1957 {
1958 /* ampersand-form of call, use @_ instead of stack */
1959 AV *av = GvAV (PL_defgv);
1960 arg = AvARRAY (av);
1961 items = AvFILLp (av) + 1;
1962 }
1963
1964 /* now call the init function, which needs to set up slf_frame */
1965 ((coro_slf_cb)CvXSUBANY (GvCV (gv)).any_ptr)
1966 (aTHX_ &slf_frame, GvCV (gv), arg, items);
1967
1968 /* pop args */
1969 SP = PL_stack_base + POPMARK;
1970
1971 PUTBACK;
1972 }
1973
1974 /* now that we have a slf_frame, interpret it! */
1975 /* we use a callback system not to make the code needlessly */
1976 /* complicated, but so we can run multiple perl coros from one cctx */
1977
1978 do
1979 {
1980 struct coro_transfer_args ta;
1981
1982 slf_frame.prepare (aTHX_ &ta);
1983 TRANSFER (ta, 0);
1984
1985 checkmark = PL_stack_sp - PL_stack_base;
1986 }
1987 while (slf_frame.check (aTHX_ &slf_frame));
1988
1989 slf_frame.prepare = 0; /* invalidate the frame, we are done processing it */
1990
1991 /* exception handling */
1992 if (expect_false (CORO_THROW))
1993 {
1994 SV *exception = sv_2mortal (CORO_THROW);
1995
1996 CORO_THROW = 0;
1997 sv_setsv (ERRSV, exception);
1998 croak (0);
1999 }
2000
2001 /* return value handling - mostly like entersub */
2002 /* make sure we put something on the stack in scalar context */
2003 if (GIMME_V == G_SCALAR)
2004 {
2005 dSP;
2006 SV **bot = PL_stack_base + checkmark;
2007
2008 if (sp == bot) /* too few, push undef */
2009 bot [1] = &PL_sv_undef;
2010 else if (sp != bot + 1) /* too many, take last one */
2011 bot [1] = *sp;
2012
2013 SP = bot + 1;
2014
2015 PUTBACK;
2016 }
2017
2018 return NORMAL;
2019}
2020
2021static void
2022api_execute_slf (pTHX_ CV *cv, coro_slf_cb init_cb, I32 ax)
2023{
2024 int i;
2025 SV **arg = PL_stack_base + ax;
2026 int items = PL_stack_sp - arg + 1;
2027
2028 assert (("FATAL: SLF call with illegal CV value", !CvANON (cv)));
2029
2030 if (PL_op->op_ppaddr != PL_ppaddr [OP_ENTERSUB]
2031 && PL_op->op_ppaddr != pp_slf)
2032 croak ("FATAL: Coro SLF calls can only be made normally, not via goto or any other means, caught");
2033
2034 CvFLAGS (cv) |= CVf_SLF;
2035 CvXSUBANY (cv).any_ptr = (void *)init_cb;
2036 slf_cv = cv;
2037
2038 /* we patch the op, and then re-run the whole call */
2039 /* we have to put the same argument on the stack for this to work */
2040 /* and this will be done by pp_restore */
2041 slf_restore.op_next = (OP *)&slf_restore;
2042 slf_restore.op_type = OP_CUSTOM;
2043 slf_restore.op_ppaddr = pp_restore;
2044 slf_restore.op_first = PL_op;
2045
2046 slf_ax = ax - 1; /* undo the ax++ inside dAXMARK */
2047
2048 if (PL_op->op_flags & OPf_STACKED)
2049 {
2050 if (items > slf_arga)
2051 {
2052 slf_arga = items;
2053 free (slf_argv);
2054 slf_argv = malloc (slf_arga * sizeof (SV *));
2055 }
2056
2057 slf_argc = items;
2058
2059 for (i = 0; i < items; ++i)
2060 slf_argv [i] = SvREFCNT_inc (arg [i]);
2061 }
2062 else
2063 slf_argc = 0;
2064
2065 PL_op->op_ppaddr = pp_slf;
2066 PL_op->op_type = OP_CUSTOM; /* maybe we should leave it at entersub? */
2067
2068 PL_op = (OP *)&slf_restore;
2069}
2070
2071/*****************************************************************************/
2072/* PerlIO::cede */
2073
2074typedef struct
2075{
2076 PerlIOBuf base;
2077 NV next, every;
2078} PerlIOCede;
2079
2080static IV
2081PerlIOCede_pushed (pTHX_ PerlIO *f, const char *mode, SV *arg, PerlIO_funcs *tab)
2082{
2083 PerlIOCede *self = PerlIOSelf (f, PerlIOCede);
2084
2085 self->every = SvCUR (arg) ? SvNV (arg) : 0.01;
2086 self->next = nvtime () + self->every;
2087
2088 return PerlIOBuf_pushed (aTHX_ f, mode, Nullsv, tab);
2089}
2090
2091static SV *
2092PerlIOCede_getarg (pTHX_ PerlIO *f, CLONE_PARAMS *param, int flags)
2093{
2094 PerlIOCede *self = PerlIOSelf (f, PerlIOCede);
2095
2096 return newSVnv (self->every);
2097}
2098
2099static IV
2100PerlIOCede_flush (pTHX_ PerlIO *f)
2101{
2102 PerlIOCede *self = PerlIOSelf (f, PerlIOCede);
2103 double now = nvtime ();
2104
2105 if (now >= self->next)
2106 {
2107 api_cede (aTHX);
2108 self->next = now + self->every;
2109 }
2110
2111 return PerlIOBuf_flush (aTHX_ f);
2112}
2113
2114static PerlIO_funcs PerlIO_cede =
2115{
2116 sizeof(PerlIO_funcs),
2117 "cede",
2118 sizeof(PerlIOCede),
2119 PERLIO_K_DESTRUCT | PERLIO_K_RAW,
2120 PerlIOCede_pushed,
2121 PerlIOBuf_popped,
2122 PerlIOBuf_open,
2123 PerlIOBase_binmode,
2124 PerlIOCede_getarg,
2125 PerlIOBase_fileno,
2126 PerlIOBuf_dup,
2127 PerlIOBuf_read,
2128 PerlIOBuf_unread,
2129 PerlIOBuf_write,
2130 PerlIOBuf_seek,
2131 PerlIOBuf_tell,
2132 PerlIOBuf_close,
2133 PerlIOCede_flush,
2134 PerlIOBuf_fill,
2135 PerlIOBase_eof,
2136 PerlIOBase_error,
2137 PerlIOBase_clearerr,
2138 PerlIOBase_setlinebuf,
2139 PerlIOBuf_get_base,
2140 PerlIOBuf_bufsiz,
2141 PerlIOBuf_get_ptr,
2142 PerlIOBuf_get_cnt,
2143 PerlIOBuf_set_ptrcnt,
2144};
2145
2146/*****************************************************************************/
2147/* Coro::Semaphore & Coro::Signal */
2148
2149static SV *
2150coro_waitarray_new (pTHX_ int count)
2151{
2152 /* a semaphore contains a counter IV in $sem->[0] and any waiters after that */
2153 AV *av = newAV ();
2154 SV **ary;
2155
2156 /* unfortunately, building manually saves memory */
2157 Newx (ary, 2, SV *);
2158 AvALLOC (av) = ary;
2159 /*AvARRAY (av) = ary;*/
2160 SvPVX ((SV *)av) = (char *)ary; /* 5.8.8 needs this syntax instead of AvARRAY = ary */
2161 AvMAX (av) = 1;
2162 AvFILLp (av) = 0;
2163 ary [0] = newSViv (count);
2164
2165 return newRV_noinc ((SV *)av);
2166}
2167
2168/* semaphore */
2169
2170static void
2171coro_semaphore_adjust (pTHX_ AV *av, IV adjust)
2172{
2173 SV *count_sv = AvARRAY (av)[0];
2174 IV count = SvIVX (count_sv);
2175
2176 count += adjust;
2177 SvIVX (count_sv) = count;
2178
2179 /* now wake up as many waiters as are expected to lock */
2180 while (count > 0 && AvFILLp (av) > 0)
2181 {
2182 SV *cb;
2183
2184 /* swap first two elements so we can shift a waiter */
2185 AvARRAY (av)[0] = AvARRAY (av)[1];
2186 AvARRAY (av)[1] = count_sv;
2187 cb = av_shift (av);
2188
2189 if (SvOBJECT (cb))
2190 {
2191 api_ready (aTHX_ cb);
2192 --count;
2193 }
2194 else if (SvTYPE (cb) == SVt_PVCV)
2195 {
2196 dSP;
2197 PUSHMARK (SP);
2198 XPUSHs (sv_2mortal (newRV_inc ((SV *)av)));
2199 PUTBACK;
2200 call_sv (cb, G_VOID | G_DISCARD | G_EVAL | G_KEEPERR);
2201 }
2202
2203 SvREFCNT_dec (cb);
2204 }
2205}
2206
2207static void
2208coro_semaphore_on_destroy (pTHX_ struct coro *coro)
2209{
2210 /* call $sem->adjust (0) to possibly wake up some other waiters */
2211 coro_semaphore_adjust (aTHX_ (AV *)coro->slf_frame.data, 0);
2212}
2213
2214static int
2215slf_check_semaphore_down_or_wait (pTHX_ struct CoroSLF *frame, int acquire)
2216{
2217 AV *av = (AV *)frame->data;
2218 SV *count_sv = AvARRAY (av)[0];
2219
2220 /* if we are about to throw, don't actually acquire the lock, just throw */
2221 if (CORO_THROW)
2222 return 0;
2223 else if (SvIVX (count_sv) > 0)
2224 {
2225 SvSTATE_current->on_destroy = 0;
2226
2227 if (acquire)
2228 SvIVX (count_sv) = SvIVX (count_sv) - 1;
2229 else
2230 coro_semaphore_adjust (aTHX_ av, 0);
2231
2232 return 0;
2233 }
2234 else
2235 {
2236 int i;
2237 /* if we were woken up but can't down, we look through the whole */
2238 /* waiters list and only add us if we aren't in there already */
2239 /* this avoids some degenerate memory usage cases */
2240
2241 for (i = 1; i <= AvFILLp (av); ++i)
2242 if (AvARRAY (av)[i] == SvRV (coro_current))
2243 return 1;
2244
2245 av_push (av, SvREFCNT_inc (SvRV (coro_current)));
2246 return 1;
2247 }
2248}
2249
2250static int
2251slf_check_semaphore_down (pTHX_ struct CoroSLF *frame)
2252{
2253 return slf_check_semaphore_down_or_wait (aTHX_ frame, 1);
2254}
2255
2256static int
2257slf_check_semaphore_wait (pTHX_ struct CoroSLF *frame)
2258{
2259 return slf_check_semaphore_down_or_wait (aTHX_ frame, 0);
2260}
2261
2262static void
2263slf_init_semaphore_down_or_wait (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items)
2264{
2265 AV *av = (AV *)SvRV (arg [0]);
2266
2267 if (SvIVX (AvARRAY (av)[0]) > 0)
2268 {
2269 frame->data = (void *)av;
2270 frame->prepare = prepare_nop;
2271 }
2272 else
2273 {
2274 av_push (av, SvREFCNT_inc (SvRV (coro_current)));
2275
2276 frame->data = (void *)sv_2mortal (SvREFCNT_inc ((SV *)av));
2277 frame->prepare = prepare_schedule;
2278
2279 /* to avoid race conditions when a woken-up coro gets terminated */
2280 /* we arrange for a temporary on_destroy that calls adjust (0) */
2281 SvSTATE_current->on_destroy = coro_semaphore_on_destroy;
2282 }
2283}
2284
2285static void
2286slf_init_semaphore_down (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items)
2287{
2288 slf_init_semaphore_down_or_wait (aTHX_ frame, cv, arg, items);
2289 frame->check = slf_check_semaphore_down;
2290}
2291
2292static void
2293slf_init_semaphore_wait (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items)
2294{
2295 if (items >= 2)
2296 {
2297 /* callback form */
2298 AV *av = (AV *)SvRV (arg [0]);
2299 CV *cb_cv = coro_sv_2cv (arg [1]);
2300
2301 av_push (av, (SV *)SvREFCNT_inc_NN (cb_cv));
2302
2303 if (SvIVX (AvARRAY (av)[0]) > 0)
2304 coro_semaphore_adjust (aTHX_ av, 0);
2305
2306 frame->prepare = prepare_nop;
2307 frame->check = slf_check_nop;
2308 }
2309 else
2310 {
2311 slf_init_semaphore_down_or_wait (aTHX_ frame, cv, arg, items);
2312 frame->check = slf_check_semaphore_wait;
2313 }
2314}
2315
2316/* signal */
2317
2318static void
2319coro_signal_wake (pTHX_ AV *av, int count)
2320{
2321 SvIVX (AvARRAY (av)[0]) = 0;
2322
2323 /* now signal count waiters */
2324 while (count > 0 && AvFILLp (av) > 0)
2325 {
2326 SV *cb;
2327
2328 /* swap first two elements so we can shift a waiter */
2329 cb = AvARRAY (av)[0];
2330 AvARRAY (av)[0] = AvARRAY (av)[1];
2331 AvARRAY (av)[1] = cb;
2332
2333 cb = av_shift (av);
2334
2335 api_ready (aTHX_ cb);
2336 sv_setiv (cb, 0); /* signal waiter */
2337 SvREFCNT_dec (cb);
2338
2339 --count;
2340 }
2341}
2342
2343static int
2344slf_check_signal_wait (pTHX_ struct CoroSLF *frame)
2345{
2346 /* if we are about to throw, also stop waiting */
2347 return SvROK ((SV *)frame->data) && !CORO_THROW;
2348}
2349
2350static void
2351slf_init_signal_wait (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items)
2352{
2353 AV *av = (AV *)SvRV (arg [0]);
2354
2355 if (SvIVX (AvARRAY (av)[0]))
2356 {
2357 SvIVX (AvARRAY (av)[0]) = 0;
2358 frame->prepare = prepare_nop;
2359 frame->check = slf_check_nop;
2360 }
2361 else
2362 {
2363 SV *waiter = newRV_inc (SvRV (coro_current)); /* owned by signal av */
2364
2365 av_push (av, waiter);
2366
2367 frame->data = (void *)sv_2mortal (SvREFCNT_inc_NN (waiter)); /* owned by process */
2368 frame->prepare = prepare_schedule;
2369 frame->check = slf_check_signal_wait;
2370 }
2371}
2372
2373/*****************************************************************************/
2374/* Coro::AIO */
2375
2376#define CORO_MAGIC_type_aio PERL_MAGIC_ext
2377
2378/* helper storage struct */
2379struct io_state
2380{
2381 int errorno;
2382 I32 laststype; /* U16 in 5.10.0 */
2383 int laststatval;
2384 Stat_t statcache;
2385};
2386
2387static void
2388coro_aio_callback (pTHX_ CV *cv)
2389{
2390 dXSARGS;
2391 AV *state = (AV *)GENSUB_ARG;
2392 SV *coro = av_pop (state);
2393 SV *data_sv = newSV (sizeof (struct io_state));
2394
2395 av_extend (state, items);
2396
2397 sv_upgrade (data_sv, SVt_PV);
2398 SvCUR_set (data_sv, sizeof (struct io_state));
2399 SvPOK_only (data_sv);
2400
2401 {
2402 struct io_state *data = (struct io_state *)SvPVX (data_sv);
2403
2404 data->errorno = errno;
2405 data->laststype = PL_laststype;
2406 data->laststatval = PL_laststatval;
2407 data->statcache = PL_statcache;
2408 }
2409
2410 /* now build the result vector out of all the parameters and the data_sv */
2411 {
2412 int i;
2413
2414 for (i = 0; i < items; ++i)
2415 av_push (state, SvREFCNT_inc_NN (ST (i)));
2416 }
2417
2418 av_push (state, data_sv);
2419
2420 api_ready (aTHX_ coro);
2421 SvREFCNT_dec (coro);
2422 SvREFCNT_dec ((AV *)state);
2423}
2424
2425static int
2426slf_check_aio_req (pTHX_ struct CoroSLF *frame)
2427{
2428 AV *state = (AV *)frame->data;
2429
2430 /* if we are about to throw, return early */
2431 /* this does not cancel the aio request, but at least */
2432 /* it quickly returns */
2433 if (CORO_THROW)
2434 return 0;
2435
2436 /* one element that is an RV? repeat! */
2437 if (AvFILLp (state) == 0 && SvROK (AvARRAY (state)[0]))
2438 return 1;
2439
2440 /* restore status */
2441 {
2442 SV *data_sv = av_pop (state);
2443 struct io_state *data = (struct io_state *)SvPVX (data_sv);
2444
2445 errno = data->errorno;
2446 PL_laststype = data->laststype;
2447 PL_laststatval = data->laststatval;
2448 PL_statcache = data->statcache;
2449
2450 SvREFCNT_dec (data_sv);
2451 }
2452
2453 /* push result values */
2454 {
2455 dSP;
2456 int i;
2457
2458 EXTEND (SP, AvFILLp (state) + 1);
2459 for (i = 0; i <= AvFILLp (state); ++i)
2460 PUSHs (sv_2mortal (SvREFCNT_inc_NN (AvARRAY (state)[i])));
2461
2462 PUTBACK;
2463 }
2464
2465 return 0;
2466}
2467
2468static void
2469slf_init_aio_req (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items)
2470{
2471 AV *state = (AV *)sv_2mortal ((SV *)newAV ());
2472 SV *coro_hv = SvRV (coro_current);
2473 struct coro *coro = SvSTATE_hv (coro_hv);
2474
2475 /* put our coroutine id on the state arg */
2476 av_push (state, SvREFCNT_inc_NN (coro_hv));
2477
2478 /* first see whether we have a non-zero priority and set it as AIO prio */
2479 if (coro->prio)
2480 {
2481 dSP;
2482
2483 static SV *prio_cv;
2484 static SV *prio_sv;
2485
2486 if (expect_false (!prio_cv))
2487 {
2488 prio_cv = (SV *)get_cv ("IO::AIO::aioreq_pri", 0);
2489 prio_sv = newSViv (0);
2490 }
2491
2492 PUSHMARK (SP);
2493 sv_setiv (prio_sv, coro->prio);
2494 XPUSHs (prio_sv);
2495
2496 PUTBACK;
2497 call_sv (prio_cv, G_VOID | G_DISCARD);
2498 }
2499
2500 /* now call the original request */
2501 {
2502 dSP;
2503 CV *req = (CV *)CORO_MAGIC_NN ((SV *)cv, CORO_MAGIC_type_aio)->mg_obj;
2504 int i;
2505
2506 PUSHMARK (SP);
2507
2508 /* first push all args to the stack */
2509 EXTEND (SP, items + 1);
2510
2511 for (i = 0; i < items; ++i)
2512 PUSHs (arg [i]);
2513
2514 /* now push the callback closure */
2515 PUSHs (sv_2mortal (gensub (aTHX_ coro_aio_callback, (void *)SvREFCNT_inc_NN ((SV *)state))));
2516
2517 /* now call the AIO function - we assume our request is uncancelable */
2518 PUTBACK;
2519 call_sv ((SV *)req, G_VOID | G_DISCARD);
2520 }
2521
2522 /* now that the requets is going, we loop toll we have a result */
2523 frame->data = (void *)state;
2524 frame->prepare = prepare_schedule;
2525 frame->check = slf_check_aio_req;
2526}
2527
2528static void
2529coro_aio_req_xs (pTHX_ CV *cv)
2530{
2531 dXSARGS;
2532
2533 CORO_EXECUTE_SLF_XS (slf_init_aio_req);
2534
2535 XSRETURN_EMPTY;
2536}
2537
2538/*****************************************************************************/
2539
2540MODULE = Coro::State PACKAGE = Coro::State PREFIX = api_
2541
2542PROTOTYPES: DISABLE
2543
2544BOOT:
2545{
2546#ifdef USE_ITHREADS
2547# if CORO_PTHREAD
2548 coro_thx = PERL_GET_CONTEXT;
2549# endif
2550#endif
2551 BOOT_PAGESIZE;
2552
2553 irsgv = gv_fetchpv ("/" , GV_ADD|GV_NOTQUAL, SVt_PV);
2554 stdoutgv = gv_fetchpv ("STDOUT", GV_ADD|GV_NOTQUAL, SVt_PVIO);
2555
2556 orig_sigelem_get = PL_vtbl_sigelem.svt_get; PL_vtbl_sigelem.svt_get = coro_sigelem_get;
2557 orig_sigelem_set = PL_vtbl_sigelem.svt_set; PL_vtbl_sigelem.svt_set = coro_sigelem_set;
2558 orig_sigelem_clr = PL_vtbl_sigelem.svt_clear; PL_vtbl_sigelem.svt_clear = coro_sigelem_clr;
2559
2560 hv_sig = coro_get_hv (aTHX_ "SIG", TRUE);
2561 rv_diehook = newRV_inc ((SV *)gv_fetchpv ("Coro::State::diehook" , 0, SVt_PVCV));
2562 rv_warnhook = newRV_inc ((SV *)gv_fetchpv ("Coro::State::warnhook", 0, SVt_PVCV));
2563
2564 coro_state_stash = gv_stashpv ("Coro::State", TRUE);
2565
2566 newCONSTSUB (coro_state_stash, "CC_TRACE" , newSViv (CC_TRACE));
2567 newCONSTSUB (coro_state_stash, "CC_TRACE_SUB" , newSViv (CC_TRACE_SUB));
2568 newCONSTSUB (coro_state_stash, "CC_TRACE_LINE", newSViv (CC_TRACE_LINE));
2569 newCONSTSUB (coro_state_stash, "CC_TRACE_ALL" , newSViv (CC_TRACE_ALL));
2570
2571 main_mainstack = PL_mainstack;
2572 main_top_env = PL_top_env;
2573
2574 while (main_top_env->je_prev)
2575 main_top_env = main_top_env->je_prev;
2576
2577 {
2578 SV *slf = sv_2mortal (newSViv (PTR2IV (pp_slf)));
2579
2580 if (!PL_custom_op_names) PL_custom_op_names = newHV ();
2581 hv_store_ent (PL_custom_op_names, slf,
2582 newSVpv ("coro_slf", 0), 0);
2583
2584 if (!PL_custom_op_descs) PL_custom_op_descs = newHV ();
2585 hv_store_ent (PL_custom_op_descs, slf,
2586 newSVpv ("coro schedule like function", 0), 0);
2587 }
2588
2589 coroapi.ver = CORO_API_VERSION;
2590 coroapi.rev = CORO_API_REVISION;
2591
2592 coroapi.transfer = api_transfer;
2593
2594 coroapi.sv_state = SvSTATE_;
2595 coroapi.execute_slf = api_execute_slf;
2596 coroapi.prepare_nop = prepare_nop;
2597 coroapi.prepare_schedule = prepare_schedule;
2598 coroapi.prepare_cede = prepare_cede;
2599 coroapi.prepare_cede_notself = prepare_cede_notself;
2600
2601 {
2602 SV **svp = hv_fetch (PL_modglobal, "Time::NVtime", 12, 0);
2603
2604 if (!svp) croak ("Time::HiRes is required");
2605 if (!SvIOK (*svp)) croak ("Time::NVtime isn't a function pointer");
2606
2607 nvtime = INT2PTR (double (*)(), SvIV (*svp));
2608 }
2609
2610 assert (("PRIO_NORMAL must be 0", !PRIO_NORMAL));
2611}
2612
2613SV *
2614new (char *klass, ...)
2615 CODE:
2616{
2617 struct coro *coro;
2618 MAGIC *mg;
2619 HV *hv;
2620 CV *cb;
2621 int i;
2622
2623 if (items > 1)
2624 {
2625 cb = coro_sv_2cv (ST (1));
2626
2627 if (CvISXSUB (cb))
2628 croak ("Coro::State doesn't support XS functions as coroutine start, caught");
2629
2630 if (!CvROOT (cb))
2631 croak ("Coro::State doesn't support autoloaded or undefined functions as coroutine start, caught");
2632 }
2633
2634 Newz (0, coro, 1, struct coro);
2635 coro->args = newAV ();
2636 coro->flags = CF_NEW;
2637
2638 if (coro_first) coro_first->prev = coro;
2639 coro->next = coro_first;
2640 coro_first = coro;
2641
2642 coro->hv = hv = newHV ();
2643 mg = sv_magicext ((SV *)hv, 0, CORO_MAGIC_type_state, &coro_state_vtbl, (char *)coro, 0);
2644 mg->mg_flags |= MGf_DUP;
2645 RETVAL = sv_bless (newRV_noinc ((SV *)hv), gv_stashpv (klass, 1));
2646
2647 if (items > 1)
2648 {
2649 coro->startcv = SvREFCNT_inc_NN (cb);
2650
2651 av_extend (coro->args, items - 1);
2652 av_push (coro->args, SvREFCNT_inc (cb));
2653 for (i = 2; i < items; i++)
2654 av_push (coro->args, newSVsv (ST (i)));
2655 }
2656}
2657 OUTPUT:
2658 RETVAL
2659
2660void
2661transfer (...)
2662 PROTOTYPE: $$
2663 CODE:
2664 CORO_EXECUTE_SLF_XS (slf_init_transfer);
2665
2666bool
2667_destroy (SV *coro_sv)
2668 CODE:
2669 RETVAL = coro_state_destroy (aTHX_ SvSTATE (coro_sv));
2670 OUTPUT:
2671 RETVAL
2672
2673void
2674_exit (int code)
2675 PROTOTYPE: $
2676 CODE:
2677 _exit (code);
2678
2679int
2680cctx_stacksize (int new_stacksize = 0)
2681 PROTOTYPE: ;$
2682 CODE:
2683 RETVAL = cctx_stacksize;
2684 if (new_stacksize)
2685 {
2686 cctx_stacksize = new_stacksize;
2687 ++cctx_gen;
2688 }
2689 OUTPUT:
2690 RETVAL
2691
2692int
2693cctx_max_idle (int max_idle = 0)
2694 PROTOTYPE: ;$
2695 CODE:
2696 RETVAL = cctx_max_idle;
2697 if (max_idle > 1)
2698 cctx_max_idle = max_idle;
2699 OUTPUT:
2700 RETVAL
2701
2702int
2703cctx_count ()
2704 PROTOTYPE:
2705 CODE:
2706 RETVAL = cctx_count;
2707 OUTPUT:
2708 RETVAL
2709
2710int
2711cctx_idle ()
2712 PROTOTYPE:
2713 CODE:
2714 RETVAL = cctx_idle;
2715 OUTPUT:
2716 RETVAL
2717
2718void
2719list ()
2720 PROTOTYPE:
2721 PPCODE:
2722{
2723 struct coro *coro;
2724 for (coro = coro_first; coro; coro = coro->next)
2725 if (coro->hv)
2726 XPUSHs (sv_2mortal (newRV_inc ((SV *)coro->hv)));
2727}
2728
2729void
2730call (Coro::State coro, SV *coderef)
2731 ALIAS:
2732 eval = 1
2733 CODE:
2734{
2735 if (coro->mainstack && ((coro->flags & CF_RUNNING) || coro->slot))
2736 {
2737 struct coro temp;
2738
2739 if (!(coro->flags & CF_RUNNING))
235 { 2740 {
236 /* I never used formats, so how should I know how these are implemented? */ 2741 PUTBACK;
237 /* my bold guess is as a simple, plain sub... */ 2742 save_perl (aTHX_ &temp);
238 croak ("CXt_FORMAT not yet handled. Don't switch coroutines from within formats"); 2743 load_perl (aTHX_ coro);
2744 }
2745
2746 {
2747 dSP;
2748 ENTER;
2749 SAVETMPS;
2750 PUTBACK;
2751 PUSHSTACK;
2752 PUSHMARK (SP);
2753
2754 if (ix)
2755 eval_sv (coderef, 0);
2756 else
2757 call_sv (coderef, G_KEEPERR | G_EVAL | G_VOID | G_DISCARD);
2758
2759 POPSTACK;
2760 SPAGAIN;
2761 FREETMPS;
2762 LEAVE;
2763 PUTBACK;
2764 }
2765
2766 if (!(coro->flags & CF_RUNNING))
2767 {
2768 save_perl (aTHX_ coro);
2769 load_perl (aTHX_ &temp);
2770 SPAGAIN;
239 } 2771 }
240 } 2772 }
241
242 if (top_si->si_type == PERLSI_MAIN)
243 break;
244
245 top_si = top_si->si_prev;
246 ccstk = top_si->si_cxstack;
247 cxix = top_si->si_cxix;
248 }
249
250 PUTBACK;
251 }
252
253 c->dowarn = PL_dowarn;
254 c->defav = GvAV (PL_defgv);
255 c->curstackinfo = PL_curstackinfo;
256 c->curstack = PL_curstack;
257 c->mainstack = PL_mainstack;
258 c->stack_sp = PL_stack_sp;
259 c->op = PL_op;
260 c->curpad = PL_curpad;
261 c->stack_base = PL_stack_base;
262 c->stack_max = PL_stack_max;
263 c->tmps_stack = PL_tmps_stack;
264 c->tmps_floor = PL_tmps_floor;
265 c->tmps_ix = PL_tmps_ix;
266 c->tmps_max = PL_tmps_max;
267 c->markstack = PL_markstack;
268 c->markstack_ptr = PL_markstack_ptr;
269 c->markstack_max = PL_markstack_max;
270 c->scopestack = PL_scopestack;
271 c->scopestack_ix = PL_scopestack_ix;
272 c->scopestack_max = PL_scopestack_max;
273 c->savestack = PL_savestack;
274 c->savestack_ix = PL_savestack_ix;
275 c->savestack_max = PL_savestack_max;
276 c->retstack = PL_retstack;
277 c->retstack_ix = PL_retstack_ix;
278 c->retstack_max = PL_retstack_max;
279 c->curcop = PL_curcop;
280} 2773}
281 2774
282static void 2775SV *
283LOAD(pTHX_ Coro__State c) 2776is_ready (Coro::State coro)
284{ 2777 PROTOTYPE: $
285 PL_dowarn = c->dowarn; 2778 ALIAS:
286 GvAV (PL_defgv) = c->defav; 2779 is_ready = CF_READY
287 PL_curstackinfo = c->curstackinfo; 2780 is_running = CF_RUNNING
288 PL_curstack = c->curstack; 2781 is_new = CF_NEW
289 PL_mainstack = c->mainstack; 2782 is_destroyed = CF_DESTROYED
290 PL_stack_sp = c->stack_sp; 2783 CODE:
291 PL_op = c->op; 2784 RETVAL = boolSV (coro->flags & ix);
292 PL_curpad = c->curpad; 2785 OUTPUT:
293 PL_stack_base = c->stack_base; 2786 RETVAL
294 PL_stack_max = c->stack_max;
295 PL_tmps_stack = c->tmps_stack;
296 PL_tmps_floor = c->tmps_floor;
297 PL_tmps_ix = c->tmps_ix;
298 PL_tmps_max = c->tmps_max;
299 PL_markstack = c->markstack;
300 PL_markstack_ptr = c->markstack_ptr;
301 PL_markstack_max = c->markstack_max;
302 PL_scopestack = c->scopestack;
303 PL_scopestack_ix = c->scopestack_ix;
304 PL_scopestack_max = c->scopestack_max;
305 PL_savestack = c->savestack;
306 PL_savestack_ix = c->savestack_ix;
307 PL_savestack_max = c->savestack_max;
308 PL_retstack = c->retstack;
309 PL_retstack_ix = c->retstack_ix;
310 PL_retstack_max = c->retstack_max;
311 PL_curcop = c->curcop;
312 2787
2788void
2789throw (Coro::State self, SV *throw = &PL_sv_undef)
2790 PROTOTYPE: $;$
2791 CODE:
2792{
2793 struct coro *current = SvSTATE_current;
2794 SV **throwp = self == current ? &CORO_THROW : &self->except;
2795 SvREFCNT_dec (*throwp);
2796 *throwp = SvOK (throw) ? newSVsv (throw) : 0;
2797}
2798
2799void
2800api_trace (SV *coro, int flags = CC_TRACE | CC_TRACE_SUB)
2801 PROTOTYPE: $;$
2802 C_ARGS: aTHX_ coro, flags
2803
2804SV *
2805has_cctx (Coro::State coro)
2806 PROTOTYPE: $
2807 CODE:
2808 RETVAL = boolSV (!!coro->cctx);
2809 OUTPUT:
2810 RETVAL
2811
2812int
2813is_traced (Coro::State coro)
2814 PROTOTYPE: $
2815 CODE:
2816 RETVAL = (coro->cctx ? coro->cctx->flags : 0) & CC_TRACE_ALL;
2817 OUTPUT:
2818 RETVAL
2819
2820UV
2821rss (Coro::State coro)
2822 PROTOTYPE: $
2823 ALIAS:
2824 usecount = 1
2825 CODE:
2826 switch (ix)
313 { 2827 {
314 dSP; 2828 case 0: RETVAL = coro_rss (aTHX_ coro); break;
315 CV *cv; 2829 case 1: RETVAL = coro->usecount; break;
316
317 /* now do the ugly restore mess */
318 while ((cv = (CV *)POPs))
319 {
320 AV *padlist = (AV *)POPs;
321
322 put_padlist (cv);
323 CvPADLIST(cv) = padlist;
324 CvDEPTH(cv) = (I32)POPs;
325
326#ifdef USE_THREADS
327 CvOWNER(cv) = (struct perl_thread *)POPs;
328 error does not work either
329#endif
330 } 2830 }
2831 OUTPUT:
2832 RETVAL
331 2833
332 PUTBACK; 2834void
333 } 2835force_cctx ()
334} 2836 PROTOTYPE:
2837 CODE:
2838 SvSTATE_current->cctx->idle_sp = 0;
335 2839
336/* this is an EXACT copy of S_nuke_stacks in perl.c, which is unfortunately static */ 2840void
337STATIC void 2841swap_defsv (Coro::State self)
338destroy_stacks(pTHX) 2842 PROTOTYPE: $
339{ 2843 ALIAS:
340 /* die does this while calling POPSTACK, but I just don't see why. */ 2844 swap_defav = 1
341 dounwind(-1); 2845 CODE:
2846 if (!self->slot)
2847 croak ("cannot swap state with coroutine that has no saved state,");
2848 else
2849 {
2850 SV **src = ix ? (SV **)&GvAV (PL_defgv) : &GvSV (PL_defgv);
2851 SV **dst = ix ? (SV **)&self->slot->defav : (SV **)&self->slot->defsv;
342 2852
343 /* is this ugly, I ask? */ 2853 SV *tmp = *src; *src = *dst; *dst = tmp;
344 while (PL_scopestack_ix) 2854 }
345 LEAVE;
346 2855
347 while (PL_curstackinfo->si_next)
348 PL_curstackinfo = PL_curstackinfo->si_next;
349 2856
350 while (PL_curstackinfo)
351 {
352 PERL_SI *p = PL_curstackinfo->si_prev;
353
354 SvREFCNT_dec(PL_curstackinfo->si_stack);
355 Safefree(PL_curstackinfo->si_cxstack);
356 Safefree(PL_curstackinfo);
357 PL_curstackinfo = p;
358 }
359
360 if (PL_scopestack_ix != 0)
361 Perl_warner(aTHX_ WARN_INTERNAL,
362 "Unbalanced scopes: %ld more ENTERs than LEAVEs\n",
363 (long)PL_scopestack_ix);
364 if (PL_savestack_ix != 0)
365 Perl_warner(aTHX_ WARN_INTERNAL,
366 "Unbalanced saves: %ld more saves than restores\n",
367 (long)PL_savestack_ix);
368 if (PL_tmps_floor != -1)
369 Perl_warner(aTHX_ WARN_INTERNAL,"Unbalanced tmps: %ld more allocs than frees\n",
370 (long)PL_tmps_floor + 1);
371 /*
372 */
373 Safefree(PL_tmps_stack);
374 Safefree(PL_markstack);
375 Safefree(PL_scopestack);
376 Safefree(PL_savestack);
377 Safefree(PL_retstack);
378}
379
380#define SUB_INIT "Coro::State::_newcoro"
381
382MODULE = Coro::State PACKAGE = Coro::State 2857MODULE = Coro::State PACKAGE = Coro
383
384PROTOTYPES: ENABLE
385 2858
386BOOT: 2859BOOT:
387 if (!padlist_cache) 2860{
388 padlist_cache = newHV (); 2861 int i;
389 2862
390Coro::State 2863 av_async_pool = coro_get_av (aTHX_ "Coro::async_pool", TRUE);
391_newprocess(args) 2864 sv_pool_rss = coro_get_sv (aTHX_ "Coro::POOL_RSS" , TRUE);
392 SV * args 2865 sv_pool_size = coro_get_sv (aTHX_ "Coro::POOL_SIZE" , TRUE);
2866
2867 coro_current = coro_get_sv (aTHX_ "Coro::current", FALSE);
2868 SvREADONLY_on (coro_current);
2869
2870 coro_stash = gv_stashpv ("Coro", TRUE);
2871
2872 newCONSTSUB (coro_stash, "PRIO_MAX", newSViv (PRIO_MAX));
2873 newCONSTSUB (coro_stash, "PRIO_HIGH", newSViv (PRIO_HIGH));
2874 newCONSTSUB (coro_stash, "PRIO_NORMAL", newSViv (PRIO_NORMAL));
2875 newCONSTSUB (coro_stash, "PRIO_LOW", newSViv (PRIO_LOW));
2876 newCONSTSUB (coro_stash, "PRIO_IDLE", newSViv (PRIO_IDLE));
2877 newCONSTSUB (coro_stash, "PRIO_MIN", newSViv (PRIO_MIN));
2878
2879 for (i = PRIO_MAX - PRIO_MIN + 1; i--; )
2880 coro_ready[i] = newAV ();
2881
2882 {
2883 SV *sv = coro_get_sv (aTHX_ "Coro::API", TRUE);
2884
2885 coroapi.schedule = api_schedule;
2886 coroapi.cede = api_cede;
2887 coroapi.cede_notself = api_cede_notself;
2888 coroapi.ready = api_ready;
2889 coroapi.is_ready = api_is_ready;
2890 coroapi.nready = coro_nready;
2891 coroapi.current = coro_current;
2892
2893 /*GCoroAPI = &coroapi;*/
2894 sv_setiv (sv, (IV)&coroapi);
2895 SvREADONLY_on (sv);
2896 }
2897}
2898
2899void
2900schedule (...)
2901 CODE:
2902 CORO_EXECUTE_SLF_XS (slf_init_schedule);
2903
2904void
2905cede (...)
2906 CODE:
2907 CORO_EXECUTE_SLF_XS (slf_init_cede);
2908
2909void
2910cede_notself (...)
2911 CODE:
2912 CORO_EXECUTE_SLF_XS (slf_init_cede_notself);
2913
2914void
2915_set_current (SV *current)
393 PROTOTYPE: $ 2916 PROTOTYPE: $
2917 CODE:
2918 SvREFCNT_dec (SvRV (coro_current));
2919 SvRV_set (coro_current, SvREFCNT_inc_NN (SvRV (current)));
2920
2921void
2922_set_readyhook (SV *hook)
2923 PROTOTYPE: $
394 CODE: 2924 CODE:
395 Coro__State coro; 2925 SvREFCNT_dec (coro_readyhook);
2926 coro_readyhook = SvOK (hook) ? newSVsv (hook) : 0;
396 2927
397 if (!SvROK (args) || SvTYPE (SvRV (args)) != SVt_PVAV) 2928int
398 croak ("Coro::State::newprocess expects an arrayref"); 2929prio (Coro::State coro, int newprio = 0)
2930 PROTOTYPE: $;$
2931 ALIAS:
2932 nice = 1
399 2933 CODE:
400 New (0, coro, 1, struct coro); 2934{
401
402 coro->mainstack = 0; /* actual work is done inside transfer */
403 coro->args = (AV *)SvREFCNT_inc (SvRV (args));
404
405 RETVAL = coro; 2935 RETVAL = coro->prio;
2936
2937 if (items > 1)
2938 {
2939 if (ix)
2940 newprio = coro->prio - newprio;
2941
2942 if (newprio < PRIO_MIN) newprio = PRIO_MIN;
2943 if (newprio > PRIO_MAX) newprio = PRIO_MAX;
2944
2945 coro->prio = newprio;
2946 }
2947}
2948 OUTPUT:
2949 RETVAL
2950
2951SV *
2952ready (SV *self)
2953 PROTOTYPE: $
2954 CODE:
2955 RETVAL = boolSV (api_ready (aTHX_ self));
2956 OUTPUT:
2957 RETVAL
2958
2959int
2960nready (...)
2961 PROTOTYPE:
2962 CODE:
2963 RETVAL = coro_nready;
2964 OUTPUT:
2965 RETVAL
2966
2967# for async_pool speedup
2968void
2969_pool_1 (SV *cb)
2970 CODE:
2971{
2972 HV *hv = (HV *)SvRV (coro_current);
2973 struct coro *coro = SvSTATE_hv ((SV *)hv);
2974 AV *defav = GvAV (PL_defgv);
2975 SV *invoke = hv_delete (hv, "_invoke", sizeof ("_invoke") - 1, 0);
2976 AV *invoke_av;
2977 int i, len;
2978
2979 if (!invoke)
2980 {
2981 SV *old = PL_diehook;
2982 PL_diehook = 0;
2983 SvREFCNT_dec (old);
2984 croak ("\3async_pool terminate\2\n");
2985 }
2986
2987 SvREFCNT_dec (coro->saved_deffh);
2988 coro->saved_deffh = SvREFCNT_inc_NN ((SV *)PL_defoutgv);
2989
2990 hv_store (hv, "desc", sizeof ("desc") - 1,
2991 newSVpvn ("[async_pool]", sizeof ("[async_pool]") - 1), 0);
2992
2993 invoke_av = (AV *)SvRV (invoke);
2994 len = av_len (invoke_av);
2995
2996 sv_setsv (cb, AvARRAY (invoke_av)[0]);
2997
2998 if (len > 0)
2999 {
3000 av_fill (defav, len - 1);
3001 for (i = 0; i < len; ++i)
3002 av_store (defav, i, SvREFCNT_inc_NN (AvARRAY (invoke_av)[i + 1]));
3003 }
3004}
3005
3006void
3007_pool_2 (SV *cb)
3008 CODE:
3009{
3010 HV *hv = (HV *)SvRV (coro_current);
3011 struct coro *coro = SvSTATE_hv ((SV *)hv);
3012
3013 sv_setsv (cb, &PL_sv_undef);
3014
3015 SvREFCNT_dec ((SV *)PL_defoutgv); PL_defoutgv = (GV *)coro->saved_deffh;
3016 coro->saved_deffh = 0;
3017
3018 if (coro_rss (aTHX_ coro) > SvUV (sv_pool_rss)
3019 || av_len (av_async_pool) + 1 >= SvIV (sv_pool_size))
3020 {
3021 SV *old = PL_diehook;
3022 PL_diehook = 0;
3023 SvREFCNT_dec (old);
3024 croak ("\3async_pool terminate\2\n");
3025 }
3026
3027 av_clear (GvAV (PL_defgv));
3028 hv_store (hv, "desc", sizeof ("desc") - 1,
3029 newSVpvn ("[async_pool idle]", sizeof ("[async_pool idle]") - 1), 0);
3030
3031 coro->prio = 0;
3032
3033 if (coro->cctx && (coro->cctx->flags & CC_TRACE))
3034 api_trace (aTHX_ coro_current, 0);
3035
3036 av_push (av_async_pool, newSVsv (coro_current));
3037}
3038
3039SV *
3040rouse_cb ()
3041 PROTOTYPE:
3042 CODE:
3043 RETVAL = coro_new_rouse_cb (aTHX);
3044 OUTPUT:
3045 RETVAL
3046
3047void
3048rouse_wait (...)
3049 PROTOTYPE: ;$
3050 PPCODE:
3051 CORO_EXECUTE_SLF_XS (slf_init_rouse_wait);
3052
3053
3054MODULE = Coro::State PACKAGE = PerlIO::cede
3055
3056BOOT:
3057 PerlIO_define_layer (aTHX_ &PerlIO_cede);
3058
3059
3060MODULE = Coro::State PACKAGE = Coro::Semaphore
3061
3062SV *
3063new (SV *klass, SV *count = 0)
3064 CODE:
3065 RETVAL = sv_bless (
3066 coro_waitarray_new (aTHX_ count && SvOK (count) ? SvIV (count) : 1),
3067 GvSTASH (CvGV (cv))
3068 );
3069 OUTPUT:
3070 RETVAL
3071
3072# helper for Coro::Channel
3073SV *
3074_alloc (int count)
3075 CODE:
3076 RETVAL = coro_waitarray_new (aTHX_ count);
3077 OUTPUT:
3078 RETVAL
3079
3080SV *
3081count (SV *self)
3082 CODE:
3083 RETVAL = newSVsv (AvARRAY ((AV *)SvRV (self))[0]);
3084 OUTPUT:
3085 RETVAL
3086
3087void
3088up (SV *self, int adjust = 1)
3089 ALIAS:
3090 adjust = 1
3091 CODE:
3092 coro_semaphore_adjust (aTHX_ (AV *)SvRV (self), ix ? adjust : 1);
3093
3094void
3095down (...)
3096 CODE:
3097 CORO_EXECUTE_SLF_XS (slf_init_semaphore_down);
3098
3099void
3100wait (...)
3101 CODE:
3102 CORO_EXECUTE_SLF_XS (slf_init_semaphore_wait);
3103
3104void
3105try (SV *self)
3106 PPCODE:
3107{
3108 AV *av = (AV *)SvRV (self);
3109 SV *count_sv = AvARRAY (av)[0];
3110 IV count = SvIVX (count_sv);
3111
3112 if (count > 0)
3113 {
3114 --count;
3115 SvIVX (count_sv) = count;
3116 XSRETURN_YES;
3117 }
3118 else
3119 XSRETURN_NO;
3120}
3121
3122void
3123waiters (SV *self)
3124 PPCODE:
3125{
3126 AV *av = (AV *)SvRV (self);
3127 int wcount = AvFILLp (av) + 1 - 1;
3128
3129 if (GIMME_V == G_SCALAR)
3130 XPUSHs (sv_2mortal (newSViv (wcount)));
3131 else
3132 {
3133 int i;
3134 EXTEND (SP, wcount);
3135 for (i = 1; i <= wcount; ++i)
3136 PUSHs (sv_2mortal (newRV_inc (AvARRAY (av)[i])));
3137 }
3138}
3139
3140MODULE = Coro::State PACKAGE = Coro::Signal
3141
3142SV *
3143new (SV *klass)
3144 CODE:
3145 RETVAL = sv_bless (
3146 coro_waitarray_new (aTHX_ 0),
3147 GvSTASH (CvGV (cv))
3148 );
406 OUTPUT: 3149 OUTPUT:
407 RETVAL 3150 RETVAL
408 3151
409void 3152void
410transfer(prev,next) 3153wait (...)
411 Coro::State_or_hashref prev
412 Coro::State_or_hashref next
413 CODE: 3154 CODE:
3155 CORO_EXECUTE_SLF_XS (slf_init_signal_wait);
414 3156
415 if (prev != next) 3157void
3158broadcast (SV *self)
3159 CODE:
3160{
3161 AV *av = (AV *)SvRV (self);
3162 coro_signal_wake (aTHX_ av, AvFILLp (av));
3163}
3164
3165void
3166send (SV *self)
3167 CODE:
3168{
3169 AV *av = (AV *)SvRV (self);
3170
3171 if (AvFILLp (av))
3172 coro_signal_wake (aTHX_ av, 1);
3173 else
3174 SvIVX (AvARRAY (av)[0]) = 1; /* remember the signal */
3175}
3176
3177IV
3178awaited (SV *self)
3179 CODE:
3180 RETVAL = AvFILLp ((AV *)SvRV (self)) + 1 - 1;
3181 OUTPUT:
3182 RETVAL
3183
3184
3185MODULE = Coro::State PACKAGE = Coro::AnyEvent
3186
3187BOOT:
3188 sv_activity = coro_get_sv (aTHX_ "Coro::AnyEvent::ACTIVITY", TRUE);
3189
3190void
3191_schedule (...)
3192 CODE:
3193{
3194 static int incede;
3195
3196 api_cede_notself (aTHX);
3197
3198 ++incede;
3199 while (coro_nready >= incede && api_cede (aTHX))
3200 ;
3201
3202 sv_setsv (sv_activity, &PL_sv_undef);
3203 if (coro_nready >= incede)
416 { 3204 {
3205 PUSHMARK (SP);
417 PUTBACK; 3206 PUTBACK;
418 SAVE (aTHX_ prev); 3207 call_pv ("Coro::AnyEvent::_activity", G_KEEPERR | G_EVAL | G_VOID | G_DISCARD);
419
420 /*
421 * this could be done in newprocess which would lead to
422 * extremely elegant and fast (just PUTBACK/SAVE/LOAD/SPAGAIN)
423 * code here, but lazy allocation of stacks has also
424 * some virtues and the overhead of the if() is nil.
425 */
426 if (next->mainstack)
427 {
428 LOAD (aTHX_ next);
429 next->mainstack = 0; /* unnecessary but much cleaner */
430 SPAGAIN;
431 }
432 else
433 {
434 /*
435 * emulate part of the perl startup here.
436 */
437 UNOP myop;
438
439 init_stacks (); /* from perl.c */
440 PL_op = (OP *)&myop;
441 /*PL_curcop = 0;*/
442 GvAV (PL_defgv) = (AV *)SvREFCNT_inc ((SV *)next->args);
443
444 SPAGAIN;
445 Zero(&myop, 1, UNOP);
446 myop.op_next = Nullop;
447 myop.op_flags = OPf_WANT_VOID;
448
449 PUSHMARK(SP);
450 XPUSHs ((SV*)get_cv(SUB_INIT, TRUE));
451 PUTBACK;
452 /*
453 * the next line is slightly wrong, as PL_op->op_next
454 * is actually being executed so we skip the first op.
455 * that doesn't matter, though, since it is only
456 * pp_nextstate and we never return...
457 */
458 PL_op = Perl_pp_entersub(aTHX);
459 SPAGAIN;
460
461 ENTER;
462 }
463 } 3208 }
464 3209
3210 --incede;
3211}
3212
3213
3214MODULE = Coro::State PACKAGE = Coro::AIO
3215
465void 3216void
466DESTROY(coro) 3217_register (char *target, char *proto, SV *req)
467 Coro::State coro 3218 CODE:
468 CODE: 3219{
3220 CV *req_cv = coro_sv_2cv (req);
3221 /* newXSproto doesn't return the CV on 5.8 */
3222 CV *slf_cv = newXS (target, coro_aio_req_xs, __FILE__);
3223 sv_setpv ((SV *)slf_cv, proto);
3224 sv_magicext ((SV *)slf_cv, (SV *)req_cv, CORO_MAGIC_type_aio, 0, 0, 0);
3225}
469 3226
470 if (coro->mainstack)
471 {
472 struct coro temp;
473
474 PUTBACK;
475 SAVE(aTHX_ (&temp));
476 LOAD(aTHX_ coro);
477
478 destroy_stacks ();
479 SvREFCNT_dec ((SV *)GvAV (PL_defgv));
480
481 LOAD((&temp));
482 SPAGAIN;
483 }
484
485 SvREFCNT_dec (coro->args);
486 Safefree (coro);
487
488

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines