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.308 by root, Wed Nov 19 15:09:57 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_type = OP_ENTERSUB;
877 myop.op_flags = OPf_WANT_VOID;
878
879 PUSHMARK (SP);
880 PUSHs ((SV *)coro->startcv);
881 PUTBACK;
882 PL_op = (OP *)&myop;
883 PL_op = PL_ppaddr[OP_ENTERSUB](aTHX);
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 etc. 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->saved_deffh);
935 SvREFCNT_dec (coro->rouse_cb);
936
937 coro_destruct_stacks (aTHX);
938}
939
940INLINE void
941free_coro_mortal (pTHX)
942{
943 if (expect_true (coro_mortal))
944 {
945 SvREFCNT_dec (coro_mortal);
946 coro_mortal = 0;
947 }
948}
949
950static int
951runops_trace (pTHX)
952{
953 COP *oldcop = 0;
954 int oldcxix = -2;
955 struct coro *coro = SvSTATE_current; /* trace cctx is tied to specific coro */
956 coro_cctx *cctx = coro->cctx;
957
958 while ((PL_op = CALL_FPTR (PL_op->op_ppaddr) (aTHX)))
959 {
960 PERL_ASYNC_CHECK ();
961
962 if (cctx->flags & CC_TRACE_ALL)
963 {
964 if (PL_op->op_type == OP_LEAVESUB && cctx->flags & CC_TRACE_SUB)
965 {
966 PERL_CONTEXT *cx = &cxstack[cxstack_ix];
967 SV **bot, **top;
968 AV *av = newAV (); /* return values */
969 SV **cb;
970 dSP;
971
972 GV *gv = CvGV (cx->blk_sub.cv);
973 SV *fullname = sv_2mortal (newSV (0));
974 if (isGV (gv))
975 gv_efullname3 (fullname, gv, 0);
976
977 bot = PL_stack_base + cx->blk_oldsp + 1;
978 top = cx->blk_gimme == G_ARRAY ? SP + 1
979 : cx->blk_gimme == G_SCALAR ? bot + 1
980 : bot;
981
982 av_extend (av, top - bot);
983 while (bot < top)
984 av_push (av, SvREFCNT_inc_NN (*bot++));
985
986 PL_runops = RUNOPS_DEFAULT;
987 ENTER;
988 SAVETMPS;
989 EXTEND (SP, 3);
990 PUSHMARK (SP);
991 PUSHs (&PL_sv_no);
992 PUSHs (fullname);
993 PUSHs (sv_2mortal (newRV_noinc ((SV *)av)));
994 PUTBACK;
995 cb = hv_fetch ((HV *)SvRV (coro_current), "_trace_sub_cb", sizeof ("_trace_sub_cb") - 1, 0);
996 if (cb) call_sv (*cb, G_KEEPERR | G_EVAL | G_VOID | G_DISCARD);
997 SPAGAIN;
998 FREETMPS;
999 LEAVE;
1000 PL_runops = runops_trace;
1001 }
1002
1003 if (oldcop != PL_curcop)
1004 {
1005 oldcop = PL_curcop;
1006
1007 if (PL_curcop != &PL_compiling)
1008 {
1009 SV **cb;
1010
1011 if (oldcxix != cxstack_ix && cctx->flags & CC_TRACE_SUB)
1012 {
1013 PERL_CONTEXT *cx = &cxstack[cxstack_ix];
1014
1015 if (CxTYPE (cx) == CXt_SUB && oldcxix < cxstack_ix)
1016 {
1017 runops_proc_t old_runops = PL_runops;
1018 dSP;
1019 GV *gv = CvGV (cx->blk_sub.cv);
1020 SV *fullname = sv_2mortal (newSV (0));
1021
1022 if (isGV (gv))
1023 gv_efullname3 (fullname, gv, 0);
1024
1025 PL_runops = RUNOPS_DEFAULT;
1026 ENTER;
1027 SAVETMPS;
1028 EXTEND (SP, 3);
1029 PUSHMARK (SP);
1030 PUSHs (&PL_sv_yes);
1031 PUSHs (fullname);
1032 PUSHs (CxHASARGS (cx) ? sv_2mortal (newRV_inc ((SV *)cx->blk_sub.argarray)) : &PL_sv_undef);
1033 PUTBACK;
1034 cb = hv_fetch ((HV *)SvRV (coro_current), "_trace_sub_cb", sizeof ("_trace_sub_cb") - 1, 0);
1035 if (cb) call_sv (*cb, G_KEEPERR | G_EVAL | G_VOID | G_DISCARD);
1036 SPAGAIN;
1037 FREETMPS;
1038 LEAVE;
1039 PL_runops = runops_trace;
1040 }
1041
1042 oldcxix = cxstack_ix;
1043 }
1044
1045 if (cctx->flags & CC_TRACE_LINE)
1046 {
1047 dSP;
1048
1049 PL_runops = RUNOPS_DEFAULT;
1050 ENTER;
1051 SAVETMPS;
1052 EXTEND (SP, 3);
1053 PL_runops = RUNOPS_DEFAULT;
1054 PUSHMARK (SP);
1055 PUSHs (sv_2mortal (newSVpv (OutCopFILE (oldcop), 0)));
1056 PUSHs (sv_2mortal (newSViv (CopLINE (oldcop))));
1057 PUTBACK;
1058 cb = hv_fetch ((HV *)SvRV (coro_current), "_trace_line_cb", sizeof ("_trace_line_cb") - 1, 0);
1059 if (cb) call_sv (*cb, G_KEEPERR | G_EVAL | G_VOID | G_DISCARD);
1060 SPAGAIN;
1061 FREETMPS;
1062 LEAVE;
1063 PL_runops = runops_trace;
1064 }
1065 }
1066 }
1067 }
1068 }
1069
1070 TAINT_NOT;
1071 return 0;
1072}
1073
1074static struct coro_cctx *cctx_ssl_cctx;
1075static struct CoroSLF cctx_ssl_frame;
1076
1077static void
1078slf_prepare_set_stacklevel (pTHX_ struct coro_transfer_args *ta)
1079{
1080 ta->prev = (struct coro *)cctx_ssl_cctx;
1081 ta->next = 0;
1082}
1083
1084static int
1085slf_check_set_stacklevel (pTHX_ struct CoroSLF *frame)
1086{
1087 *frame = cctx_ssl_frame;
1088
1089 return frame->check (aTHX_ frame); /* execute the restored frame - there must be one */
1090}
1091
1092/* initialises PL_top_env and injects a pseudo-slf-call to set the stacklevel */
1093static void NOINLINE
1094cctx_prepare (pTHX_ coro_cctx *cctx)
1095{
1096 PL_top_env = &PL_start_env;
1097
1098 if (cctx->flags & CC_TRACE)
1099 PL_runops = runops_trace;
1100
1101 /* we already must be executing an SLF op, there is no other valid way
1102 * that can lead to creation of a new cctx */
1103 assert (("FATAL: can't prepare slf-less cctx in Coro module (please report)",
1104 slf_frame.prepare && PL_op->op_ppaddr == pp_slf));
1105
1106 /* we must emulate leaving pp_slf, which is done inside slf_check_set_stacklevel */
1107 cctx_ssl_cctx = cctx;
1108 cctx_ssl_frame = slf_frame;
1109
1110 slf_frame.prepare = slf_prepare_set_stacklevel;
1111 slf_frame.check = slf_check_set_stacklevel;
1112}
1113
1114/* the tail of transfer: execute stuff we can only do after a transfer */
1115INLINE void
1116transfer_tail (pTHX)
1117{
1118 free_coro_mortal (aTHX);
1119}
1120
1121/*
1122 * this is a _very_ stripped down perl interpreter ;)
1123 */
1124static void
1125cctx_run (void *arg)
1126{
1127#ifdef USE_ITHREADS
1128# if CORO_PTHREAD
1129 PERL_SET_CONTEXT (coro_thx);
1130# endif
1131#endif
1132 {
1133 dTHX;
1134
1135 /* normally we would need to skip the entersub here */
1136 /* not doing so will re-execute it, which is exactly what we want */
1137 /* PL_nop = PL_nop->op_next */
1138
1139 /* inject a fake subroutine call to cctx_init */
1140 cctx_prepare (aTHX_ (coro_cctx *)arg);
1141
1142 /* cctx_run is the alternative tail of transfer() */
1143 transfer_tail (aTHX);
1144
1145 /* somebody or something will hit me for both perl_run and PL_restartop */
1146 PL_restartop = PL_op;
1147 perl_run (PL_curinterp);
1148 /*
1149 * Unfortunately, there is no way to get at the return values of the
1150 * coro body here, as perl_run destroys these
1151 */
1152
1153 /*
1154 * If perl-run returns we assume exit() was being called or the coro
1155 * fell off the end, which seems to be the only valid (non-bug)
1156 * reason for perl_run to return. We try to exit by jumping to the
1157 * bootstrap-time "top" top_env, as we cannot restore the "main"
1158 * coroutine as Coro has no such concept
1159 */
1160 PL_top_env = main_top_env;
1161 JMPENV_JUMP (2); /* I do not feel well about the hardcoded 2 at all */
1162 }
1163}
1164
1165static coro_cctx *
1166cctx_new ()
1167{
1168 coro_cctx *cctx;
1169
1170 ++cctx_count;
1171 New (0, cctx, 1, coro_cctx);
1172
1173 cctx->gen = cctx_gen;
1174 cctx->flags = 0;
1175 cctx->idle_sp = 0; /* can be accessed by transfer between cctx_run and set_stacklevel, on throw */
1176
1177 return cctx;
1178}
1179
1180/* create a new cctx only suitable as source */
1181static coro_cctx *
1182cctx_new_empty ()
1183{
1184 coro_cctx *cctx = cctx_new ();
1185
1186 cctx->sptr = 0;
1187 coro_create (&cctx->cctx, 0, 0, 0, 0);
1188
1189 return cctx;
1190}
1191
1192/* create a new cctx suitable as destination/running a perl interpreter */
1193static coro_cctx *
1194cctx_new_run ()
1195{
1196 coro_cctx *cctx = cctx_new ();
1197 void *stack_start;
1198 size_t stack_size;
1199
1200#if HAVE_MMAP
1201 cctx->ssize = ((cctx_stacksize * sizeof (long) + PAGESIZE - 1) / PAGESIZE + CORO_STACKGUARD) * PAGESIZE;
1202 /* mmap supposedly does allocate-on-write for us */
1203 cctx->sptr = mmap (0, cctx->ssize, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
1204
1205 if (cctx->sptr != (void *)-1)
1206 {
1207 #if CORO_STACKGUARD
1208 mprotect (cctx->sptr, CORO_STACKGUARD * PAGESIZE, PROT_NONE);
1209 #endif
1210 stack_start = (char *)cctx->sptr + CORO_STACKGUARD * PAGESIZE;
1211 stack_size = cctx->ssize - CORO_STACKGUARD * PAGESIZE;
1212 cctx->flags |= CC_MAPPED;
1213 }
1214 else
1215#endif
1216 {
1217 cctx->ssize = cctx_stacksize * (long)sizeof (long);
1218 New (0, cctx->sptr, cctx_stacksize, long);
1219
1220 if (!cctx->sptr)
1221 {
1222 perror ("FATAL: unable to allocate stack for coroutine, exiting.");
1223 _exit (EXIT_FAILURE);
1224 }
1225
1226 stack_start = cctx->sptr;
1227 stack_size = cctx->ssize;
1228 }
1229
1230 #if CORO_USE_VALGRIND
1231 cctx->valgrind_id = VALGRIND_STACK_REGISTER ((char *)stack_start, (char *)stack_start + stack_size);
1232 #endif
1233
1234 coro_create (&cctx->cctx, cctx_run, (void *)cctx, stack_start, stack_size);
1235
1236 return cctx;
1237}
1238
1239static void
1240cctx_destroy (coro_cctx *cctx)
1241{
1242 if (!cctx)
1243 return;
1244
1245 --cctx_count;
1246 coro_destroy (&cctx->cctx);
1247
1248 /* coro_transfer creates new, empty cctx's */
1249 if (cctx->sptr)
1250 {
1251 #if CORO_USE_VALGRIND
1252 VALGRIND_STACK_DEREGISTER (cctx->valgrind_id);
1253 #endif
1254
1255#if HAVE_MMAP
1256 if (cctx->flags & CC_MAPPED)
1257 munmap (cctx->sptr, cctx->ssize);
1258 else
1259#endif
1260 Safefree (cctx->sptr);
1261 }
1262
1263 Safefree (cctx);
1264}
1265
1266/* wether this cctx should be destructed */
1267#define CCTX_EXPIRED(cctx) ((cctx)->gen != cctx_gen || ((cctx)->flags & CC_NOREUSE))
1268
1269static coro_cctx *
1270cctx_get (pTHX)
1271{
1272 while (expect_true (cctx_first))
1273 {
1274 coro_cctx *cctx = cctx_first;
1275 cctx_first = cctx->next;
1276 --cctx_idle;
1277
1278 if (expect_true (!CCTX_EXPIRED (cctx)))
1279 return cctx;
1280
1281 cctx_destroy (cctx);
1282 }
1283
1284 return cctx_new_run ();
1285}
1286
1287static void
1288cctx_put (coro_cctx *cctx)
1289{
1290 assert (("FATAL: cctx_put called on non-initialised cctx in Coro (please report)", cctx->sptr));
1291
1292 /* free another cctx if overlimit */
1293 if (expect_false (cctx_idle >= cctx_max_idle))
1294 {
1295 coro_cctx *first = cctx_first;
1296 cctx_first = first->next;
1297 --cctx_idle;
1298
1299 cctx_destroy (first);
1300 }
1301
1302 ++cctx_idle;
1303 cctx->next = cctx_first;
1304 cctx_first = cctx;
1305}
1306
1307/** coroutine switching *****************************************************/
1308
1309static void
1310transfer_check (pTHX_ struct coro *prev, struct coro *next)
1311{
1312 /* TODO: throwing up here is considered harmful */
1313
1314 if (expect_true (prev != next))
1315 {
1316 if (expect_false (!(prev->flags & (CF_RUNNING | CF_NEW))))
1317 croak ("Coro::State::transfer called with non-running/new prev Coro::State, but can only transfer from running or new states,");
1318
1319 if (expect_false (next->flags & CF_RUNNING))
1320 croak ("Coro::State::transfer called with running next Coro::State, but can only transfer to inactive states,");
1321
1322 if (expect_false (next->flags & CF_DESTROYED))
1323 croak ("Coro::State::transfer called with destroyed next Coro::State, but can only transfer to inactive states,");
1324
1325#if !PERL_VERSION_ATLEAST (5,10,0)
1326 if (expect_false (PL_lex_state != LEX_NOTPARSING))
1327 croak ("Coro::State::transfer called while parsing, but this is not supported in your perl version,");
1328#endif
1329 }
1330}
1331
1332/* always use the TRANSFER macro */
1333static void NOINLINE /* noinline so we have a fixed stackframe */
1334transfer (pTHX_ struct coro *prev, struct coro *next, int force_cctx)
1335{
1336 dSTACKLEVEL;
1337
1338 /* sometimes transfer is only called to set idle_sp */
1339 if (expect_false (!next))
1340 {
1341 ((coro_cctx *)prev)->idle_sp = STACKLEVEL;
1342 assert (((coro_cctx *)prev)->idle_te = PL_top_env); /* just for the side-effect when asserts are enabled */
1343 }
1344 else if (expect_true (prev != next))
1345 {
1346 coro_cctx *prev__cctx;
1347
1348 if (expect_false (prev->flags & CF_NEW))
1349 {
1350 /* create a new empty/source context */
1351 prev->cctx = cctx_new_empty ();
1352 prev->flags &= ~CF_NEW;
1353 prev->flags |= CF_RUNNING;
1354 }
1355
1356 prev->flags &= ~CF_RUNNING;
1357 next->flags |= CF_RUNNING;
1358
1359 /* first get rid of the old state */
1360 save_perl (aTHX_ prev);
1361
1362 if (expect_false (next->flags & CF_NEW))
1363 {
1364 /* need to start coroutine */
1365 next->flags &= ~CF_NEW;
1366 /* setup coroutine call */
1367 coro_setup (aTHX_ next);
1368 }
1369 else
1370 load_perl (aTHX_ next);
1371
1372 prev__cctx = prev->cctx;
1373
1374 /* possibly untie and reuse the cctx */
1375 if (expect_true (
1376 prev__cctx->idle_sp == STACKLEVEL
1377 && !(prev__cctx->flags & CC_TRACE)
1378 && !force_cctx
1379 ))
1380 {
1381 /* I assume that stacklevel is a stronger indicator than PL_top_env changes */
1382 assert (("FATAL: current top_env must equal previous top_env in Coro (please report)", PL_top_env == prev__cctx->idle_te));
1383
1384 prev->cctx = 0;
1385
1386 /* if the cctx is about to be destroyed we need to make sure we won't see it in cctx_get */
1387 /* without this the next cctx_get might destroy the prev__cctx while still in use */
1388 if (expect_false (CCTX_EXPIRED (prev__cctx)))
1389 if (!next->cctx)
1390 next->cctx = cctx_get (aTHX);
1391
1392 cctx_put (prev__cctx);
1393 }
1394
1395 ++next->usecount;
1396
1397 if (expect_true (!next->cctx))
1398 next->cctx = cctx_get (aTHX);
1399
1400 if (expect_false (prev__cctx != next->cctx))
1401 {
1402 prev__cctx->top_env = PL_top_env;
1403 PL_top_env = next->cctx->top_env;
1404 coro_transfer (&prev__cctx->cctx, &next->cctx->cctx);
1405 }
1406
1407 transfer_tail (aTHX);
1408 }
1409}
1410
1411#define TRANSFER(ta, force_cctx) transfer (aTHX_ (ta).prev, (ta).next, (force_cctx))
1412#define TRANSFER_CHECK(ta) transfer_check (aTHX_ (ta).prev, (ta).next)
1413
1414/** high level stuff ********************************************************/
1415
1416static int
1417coro_state_destroy (pTHX_ struct coro *coro)
1418{
1419 if (coro->flags & CF_DESTROYED)
1420 return 0;
1421
1422 if (coro->on_destroy)
1423 coro->on_destroy (aTHX_ coro);
1424
1425 coro->flags |= CF_DESTROYED;
1426
1427 if (coro->flags & CF_READY)
1428 {
1429 /* reduce nready, as destroying a ready coro effectively unreadies it */
1430 /* alternative: look through all ready queues and remove the coro */
1431 --coro_nready;
1432 }
1433 else
1434 coro->flags |= CF_READY; /* make sure it is NOT put into the readyqueue */
1435
1436 if (coro->mainstack && coro->mainstack != main_mainstack)
1437 {
1438 struct coro temp;
1439
1440 assert (("FATAL: tried to destroy currently running coroutine (please report)", !(coro->flags & CF_RUNNING)));
1441
1442 save_perl (aTHX_ &temp);
1443 load_perl (aTHX_ coro);
1444
1445 coro_destruct (aTHX_ coro);
1446
1447 load_perl (aTHX_ &temp);
1448
1449 coro->slot = 0;
1450 }
1451
1452 cctx_destroy (coro->cctx);
1453 SvREFCNT_dec (coro->startcv);
1454 SvREFCNT_dec (coro->args);
1455 SvREFCNT_dec (CORO_THROW);
1456
1457 if (coro->next) coro->next->prev = coro->prev;
1458 if (coro->prev) coro->prev->next = coro->next;
1459 if (coro == coro_first) coro_first = coro->next;
1460
1461 return 1;
1462}
1463
1464static int
1465coro_state_free (pTHX_ SV *sv, MAGIC *mg)
1466{
1467 struct coro *coro = (struct coro *)mg->mg_ptr;
1468 mg->mg_ptr = 0;
1469
1470 coro->hv = 0;
1471
1472 if (--coro->refcnt < 0)
1473 {
1474 coro_state_destroy (aTHX_ coro);
1475 Safefree (coro);
1476 }
1477
1478 return 0;
1479}
1480
1481static int
1482coro_state_dup (pTHX_ MAGIC *mg, CLONE_PARAMS *params)
1483{
1484 struct coro *coro = (struct coro *)mg->mg_ptr;
1485
1486 ++coro->refcnt;
1487
1488 return 0;
1489}
1490
1491static MGVTBL coro_state_vtbl = {
1492 0, 0, 0, 0,
1493 coro_state_free,
1494 0,
1495#ifdef MGf_DUP
1496 coro_state_dup,
1497#else
1498# define MGf_DUP 0
1499#endif
1500};
1501
1502static void
1503prepare_transfer (pTHX_ struct coro_transfer_args *ta, SV *prev_sv, SV *next_sv)
1504{
1505 ta->prev = SvSTATE (prev_sv);
1506 ta->next = SvSTATE (next_sv);
1507 TRANSFER_CHECK (*ta);
1508}
1509
1510static void
1511api_transfer (pTHX_ SV *prev_sv, SV *next_sv)
1512{
1513 struct coro_transfer_args ta;
1514
1515 prepare_transfer (aTHX_ &ta, prev_sv, next_sv);
1516 TRANSFER (ta, 1);
1517}
1518
1519/*****************************************************************************/
1520/* gensub: simple closure generation utility */
1521
1522#define GENSUB_ARG CvXSUBANY (cv).any_ptr
1523
1524/* create a closure from XS, returns a code reference */
1525/* the arg can be accessed via GENSUB_ARG from the callback */
1526/* the callback must use dXSARGS/XSRETURN */
1527static SV *
1528gensub (pTHX_ void (*xsub)(pTHX_ CV *), void *arg)
1529{
1530 CV *cv = (CV *)newSV (0);
1531
1532 sv_upgrade ((SV *)cv, SVt_PVCV);
1533
1534 CvANON_on (cv);
1535 CvISXSUB_on (cv);
1536 CvXSUB (cv) = xsub;
1537 GENSUB_ARG = arg;
1538
1539 return newRV_noinc ((SV *)cv);
1540}
1541
1542/** Coro ********************************************************************/
1543
1544INLINE void
1545coro_enq (pTHX_ struct coro *coro)
1546{
1547 av_push (coro_ready [coro->prio - PRIO_MIN], SvREFCNT_inc_NN (coro->hv));
1548}
1549
1550INLINE SV *
1551coro_deq (pTHX)
1552{
1553 int prio;
1554
1555 for (prio = PRIO_MAX - PRIO_MIN + 1; --prio >= 0; )
1556 if (AvFILLp (coro_ready [prio]) >= 0)
1557 return av_shift (coro_ready [prio]);
1558
1559 return 0;
1560}
1561
1562static int
1563api_ready (pTHX_ SV *coro_sv)
1564{
1565 struct coro *coro;
1566 SV *sv_hook;
1567 void (*xs_hook)(void);
1568
1569 if (SvROK (coro_sv))
1570 coro_sv = SvRV (coro_sv);
1571
1572 coro = SvSTATE (coro_sv);
1573
1574 if (coro->flags & CF_READY)
1575 return 0;
1576
1577 coro->flags |= CF_READY;
1578
1579 sv_hook = coro_nready ? 0 : coro_readyhook;
1580 xs_hook = coro_nready ? 0 : coroapi.readyhook;
1581
1582 coro_enq (aTHX_ coro);
1583 ++coro_nready;
1584
1585 if (sv_hook)
1586 {
1587 dSP;
1588
1589 ENTER;
1590 SAVETMPS;
1591
1592 PUSHMARK (SP);
1593 PUTBACK;
1594 call_sv (sv_hook, G_VOID | G_DISCARD);
1595
1596 FREETMPS;
1597 LEAVE;
1598 }
1599
1600 if (xs_hook)
1601 xs_hook ();
1602
1603 return 1;
1604}
1605
1606static int
1607api_is_ready (pTHX_ SV *coro_sv)
1608{
1609 return !!(SvSTATE (coro_sv)->flags & CF_READY);
1610}
1611
1612INLINE void
1613prepare_schedule (pTHX_ struct coro_transfer_args *ta)
1614{
1615 SV *prev_sv, *next_sv;
1616
1617 for (;;)
1618 {
1619 next_sv = coro_deq (aTHX);
1620
1621 /* nothing to schedule: call the idle handler */
1622 if (expect_false (!next_sv))
1623 {
1624 dSP;
1625
1626 ENTER;
1627 SAVETMPS;
1628
1629 PUSHMARK (SP);
1630 PUTBACK;
1631 call_sv (get_sv ("Coro::idle", FALSE), G_VOID | G_DISCARD);
1632
1633 FREETMPS;
1634 LEAVE;
1635 continue;
1636 }
1637
1638 ta->next = SvSTATE_hv (next_sv);
1639
1640 /* cannot transfer to destroyed coros, skip and look for next */
1641 if (expect_false (ta->next->flags & CF_DESTROYED))
1642 {
1643 SvREFCNT_dec (next_sv);
1644 /* coro_nready has already been taken care of by destroy */
1645 continue;
1646 }
1647
1648 --coro_nready;
1649 break;
1650 }
1651
1652 /* free this only after the transfer */
1653 prev_sv = SvRV (coro_current);
1654 ta->prev = SvSTATE_hv (prev_sv);
1655 TRANSFER_CHECK (*ta);
1656 assert (("FATAL: next coroutine isn't marked as ready in Coro (please report)", ta->next->flags & CF_READY));
1657 ta->next->flags &= ~CF_READY;
1658 SvRV_set (coro_current, next_sv);
1659
1660 free_coro_mortal (aTHX);
1661 coro_mortal = prev_sv;
1662}
1663
1664INLINE void
1665prepare_cede (pTHX_ struct coro_transfer_args *ta)
1666{
1667 api_ready (aTHX_ coro_current);
1668 prepare_schedule (aTHX_ ta);
1669}
1670
1671INLINE void
1672prepare_cede_notself (pTHX_ struct coro_transfer_args *ta)
1673{
1674 SV *prev = SvRV (coro_current);
1675
1676 if (coro_nready)
1677 {
1678 prepare_schedule (aTHX_ ta);
1679 api_ready (aTHX_ prev);
1680 }
1681 else
1682 prepare_nop (aTHX_ ta);
1683}
1684
1685static void
1686api_schedule (pTHX)
1687{
1688 struct coro_transfer_args ta;
1689
1690 prepare_schedule (aTHX_ &ta);
1691 TRANSFER (ta, 1);
1692}
1693
1694static int
1695api_cede (pTHX)
1696{
1697 struct coro_transfer_args ta;
1698
1699 prepare_cede (aTHX_ &ta);
1700
1701 if (expect_true (ta.prev != ta.next))
1702 {
1703 TRANSFER (ta, 1);
1704 return 1;
1705 }
1706 else
1707 return 0;
1708}
1709
1710static int
1711api_cede_notself (pTHX)
1712{
1713 if (coro_nready)
1714 {
1715 struct coro_transfer_args ta;
1716
1717 prepare_cede_notself (aTHX_ &ta);
1718 TRANSFER (ta, 1);
1719 return 1;
1720 }
1721 else
1722 return 0;
1723}
1724
1725static void
1726api_trace (pTHX_ SV *coro_sv, int flags)
1727{
1728 struct coro *coro = SvSTATE (coro_sv);
1729
1730 if (flags & CC_TRACE)
1731 {
1732 if (!coro->cctx)
1733 coro->cctx = cctx_new_run ();
1734 else if (!(coro->cctx->flags & CC_TRACE))
1735 croak ("cannot enable tracing on coroutine with custom stack,");
1736
1737 coro->cctx->flags |= CC_NOREUSE | (flags & (CC_TRACE | CC_TRACE_ALL));
1738 }
1739 else if (coro->cctx && coro->cctx->flags & CC_TRACE)
1740 {
1741 coro->cctx->flags &= ~(CC_TRACE | CC_TRACE_ALL);
1742
1743 if (coro->flags & CF_RUNNING)
1744 PL_runops = RUNOPS_DEFAULT;
1745 else
1746 coro->slot->runops = RUNOPS_DEFAULT;
1747 }
1748}
1749
1750/*****************************************************************************/
1751/* rouse callback */
1752
1753#define CORO_MAGIC_type_rouse PERL_MAGIC_ext
1754
1755static void
1756coro_rouse_callback (pTHX_ CV *cv)
1757{
1758 dXSARGS;
1759 SV *data = (SV *)GENSUB_ARG;
1760
1761 if (SvTYPE (SvRV (data)) != SVt_PVAV)
1762 {
1763 /* first call, set args */
1764 int i;
1765 AV *av = newAV ();
1766 SV *coro = SvRV (data);
1767
1768 SvRV_set (data, (SV *)av);
1769 api_ready (aTHX_ coro);
1770 SvREFCNT_dec (coro);
1771
1772 /* better take a full copy of the arguments */
1773 while (items--)
1774 av_store (av, items, newSVsv (ST (items)));
1775 }
1776
1777 XSRETURN_EMPTY;
1778}
1779
1780static int
1781slf_check_rouse_wait (pTHX_ struct CoroSLF *frame)
1782{
1783 SV *data = (SV *)frame->data;
1784
1785 if (CORO_THROW)
1786 return 0;
1787
1788 if (SvTYPE (SvRV (data)) != SVt_PVAV)
1789 return 1;
1790
1791 /* now push all results on the stack */
1792 {
1793 dSP;
1794 AV *av = (AV *)SvRV (data);
1795 int i;
1796
1797 EXTEND (SP, AvFILLp (av) + 1);
1798 for (i = 0; i <= AvFILLp (av); ++i)
1799 PUSHs (sv_2mortal (AvARRAY (av)[i]));
1800
1801 /* we have stolen the elements, so ste length to zero and free */
1802 AvFILLp (av) = -1;
1803 av_undef (av);
1804
1805 PUTBACK;
1806 }
1807
1808 return 0;
1809}
1810
1811static void
1812slf_init_rouse_wait (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items)
1813{
1814 SV *cb;
1815
1816 if (items)
1817 cb = arg [0];
1818 else
1819 {
1820 struct coro *coro = SvSTATE_current;
1821
1822 if (!coro->rouse_cb)
1823 croak ("Coro::rouse_wait called without rouse callback, and no default rouse callback found either,");
1824
1825 cb = sv_2mortal (coro->rouse_cb);
1826 coro->rouse_cb = 0;
1827 }
1828
1829 if (!SvROK (cb)
1830 || SvTYPE (SvRV (cb)) != SVt_PVCV
1831 || CvXSUB ((CV *)SvRV (cb)) != coro_rouse_callback)
1832 croak ("Coro::rouse_wait called with illegal callback argument,");
1833
1834 {
1835 CV *cv = (CV *)SvRV (cb); /* for GENSUB_ARG */
1836 SV *data = (SV *)GENSUB_ARG;
1837
1838 frame->data = (void *)data;
1839 frame->prepare = SvTYPE (SvRV (data)) == SVt_PVAV ? prepare_nop : prepare_schedule;
1840 frame->check = slf_check_rouse_wait;
1841 }
1842}
1843
1844static SV *
1845coro_new_rouse_cb (pTHX)
1846{
1847 HV *hv = (HV *)SvRV (coro_current);
1848 struct coro *coro = SvSTATE_hv (hv);
1849 SV *data = newRV_inc ((SV *)hv);
1850 SV *cb = gensub (aTHX_ coro_rouse_callback, (void *)data);
1851
1852 sv_magicext (SvRV (cb), data, CORO_MAGIC_type_rouse, 0, 0, 0);
1853 SvREFCNT_dec (data); /* magicext increases the refcount */
1854
1855 SvREFCNT_dec (coro->rouse_cb);
1856 coro->rouse_cb = SvREFCNT_inc_NN (cb);
1857
1858 return cb;
1859}
1860
1861/*****************************************************************************/
1862/* schedule-like-function opcode (SLF) */
1863
1864static UNOP slf_restore; /* restore stack as entersub did, for first-re-run */
1865static const CV *slf_cv;
1866static SV **slf_argv;
1867static int slf_argc, slf_arga; /* count, allocated */
1868static I32 slf_ax; /* top of stack, for restore */
1869
1870/* this restores the stack in the case we patched the entersub, to */
1871/* recreate the stack frame as perl will on following calls */
1872/* since entersub cleared the stack */
1873static OP *
1874pp_restore (pTHX)
1875{
1876 int i;
1877 SV **SP = PL_stack_base + slf_ax;
1878
1879 PUSHMARK (SP);
1880
1881 EXTEND (SP, slf_argc + 1);
1882
1883 for (i = 0; i < slf_argc; ++i)
1884 PUSHs (sv_2mortal (slf_argv [i]));
1885
1886 PUSHs ((SV *)CvGV (slf_cv));
1887
1888 RETURNOP (slf_restore.op_first);
1889}
1890
1891static void
1892slf_prepare_transfer (pTHX_ struct coro_transfer_args *ta)
1893{
1894 SV **arg = (SV **)slf_frame.data;
1895
1896 prepare_transfer (aTHX_ ta, arg [0], arg [1]);
1897}
1898
1899static void
1900slf_init_transfer (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items)
1901{
1902 if (items != 2)
1903 croak ("Coro::State::transfer (prev, next) expects two arguments, not %d,", items);
1904
1905 frame->prepare = slf_prepare_transfer;
1906 frame->check = slf_check_nop;
1907 frame->data = (void *)arg; /* let's hope it will stay valid */
1908}
1909
1910static void
1911slf_init_schedule (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items)
1912{
1913 frame->prepare = prepare_schedule;
1914 frame->check = slf_check_nop;
1915}
1916
1917static void
1918slf_init_cede (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items)
1919{
1920 frame->prepare = prepare_cede;
1921 frame->check = slf_check_nop;
1922}
1923
1924static void
1925slf_init_cede_notself (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items)
1926{
1927 frame->prepare = prepare_cede_notself;
1928 frame->check = slf_check_nop;
1929}
1930
1931/*
1932 * these not obviously related functions are all rolled into one
1933 * function to increase chances that they all will call transfer with the same
1934 * stack offset
1935 * SLF stands for "schedule-like-function".
1936 */
1937static OP *
1938pp_slf (pTHX)
1939{
1940 I32 checkmark; /* mark SP to see how many elements check has pushed */
1941
1942 /* set up the slf frame, unless it has already been set-up */
1943 /* the latter happens when a new coro has been started */
1944 /* or when a new cctx was attached to an existing coroutine */
1945 if (expect_true (!slf_frame.prepare))
1946 {
1947 /* first iteration */
1948 dSP;
1949 SV **arg = PL_stack_base + TOPMARK + 1;
1950 int items = SP - arg; /* args without function object */
1951 SV *gv = *sp;
1952
1953 /* do a quick consistency check on the "function" object, and if it isn't */
1954 /* for us, divert to the real entersub */
1955 if (SvTYPE (gv) != SVt_PVGV
1956 || !GvCV (gv)
1957 || !(CvFLAGS (GvCV (gv)) & CVf_SLF))
1958 return PL_ppaddr[OP_ENTERSUB](aTHX);
1959
1960 if (!(PL_op->op_flags & OPf_STACKED))
1961 {
1962 /* ampersand-form of call, use @_ instead of stack */
1963 AV *av = GvAV (PL_defgv);
1964 arg = AvARRAY (av);
1965 items = AvFILLp (av) + 1;
1966 }
1967
1968 /* now call the init function, which needs to set up slf_frame */
1969 ((coro_slf_cb)CvXSUBANY (GvCV (gv)).any_ptr)
1970 (aTHX_ &slf_frame, GvCV (gv), arg, items);
1971
1972 /* pop args */
1973 SP = PL_stack_base + POPMARK;
1974
1975 PUTBACK;
1976 }
1977
1978 /* now that we have a slf_frame, interpret it! */
1979 /* we use a callback system not to make the code needlessly */
1980 /* complicated, but so we can run multiple perl coros from one cctx */
1981
1982 do
1983 {
1984 struct coro_transfer_args ta;
1985
1986 slf_frame.prepare (aTHX_ &ta);
1987 TRANSFER (ta, 0);
1988
1989 checkmark = PL_stack_sp - PL_stack_base;
1990 }
1991 while (slf_frame.check (aTHX_ &slf_frame));
1992
1993 slf_frame.prepare = 0; /* invalidate the frame, we are done processing it */
1994
1995 /* exception handling */
1996 if (expect_false (CORO_THROW))
1997 {
1998 SV *exception = sv_2mortal (CORO_THROW);
1999
2000 CORO_THROW = 0;
2001 sv_setsv (ERRSV, exception);
2002 croak (0);
2003 }
2004
2005 /* return value handling - mostly like entersub */
2006 /* make sure we put something on the stack in scalar context */
2007 if (GIMME_V == G_SCALAR)
2008 {
2009 dSP;
2010 SV **bot = PL_stack_base + checkmark;
2011
2012 if (sp == bot) /* too few, push undef */
2013 bot [1] = &PL_sv_undef;
2014 else if (sp != bot + 1) /* too many, take last one */
2015 bot [1] = *sp;
2016
2017 SP = bot + 1;
2018
2019 PUTBACK;
2020 }
2021
2022 return NORMAL;
2023}
2024
2025static void
2026api_execute_slf (pTHX_ CV *cv, coro_slf_cb init_cb, I32 ax)
2027{
2028 int i;
2029 SV **arg = PL_stack_base + ax;
2030 int items = PL_stack_sp - arg + 1;
2031
2032 assert (("FATAL: SLF call with illegal CV value", !CvANON (cv)));
2033
2034 if (PL_op->op_ppaddr != PL_ppaddr [OP_ENTERSUB]
2035 && PL_op->op_ppaddr != pp_slf)
2036 croak ("FATAL: Coro SLF calls can only be made normally, not via goto or any other means, caught");
2037
2038 CvFLAGS (cv) |= CVf_SLF;
2039 CvXSUBANY (cv).any_ptr = (void *)init_cb;
2040 slf_cv = cv;
2041
2042 /* we patch the op, and then re-run the whole call */
2043 /* we have to put the same argument on the stack for this to work */
2044 /* and this will be done by pp_restore */
2045 slf_restore.op_next = (OP *)&slf_restore;
2046 slf_restore.op_type = OP_CUSTOM;
2047 slf_restore.op_ppaddr = pp_restore;
2048 slf_restore.op_first = PL_op;
2049
2050 slf_ax = ax - 1; /* undo the ax++ inside dAXMARK */
2051
2052 if (PL_op->op_flags & OPf_STACKED)
2053 {
2054 if (items > slf_arga)
2055 {
2056 slf_arga = items;
2057 free (slf_argv);
2058 slf_argv = malloc (slf_arga * sizeof (SV *));
2059 }
2060
2061 slf_argc = items;
2062
2063 for (i = 0; i < items; ++i)
2064 slf_argv [i] = SvREFCNT_inc (arg [i]);
2065 }
2066 else
2067 slf_argc = 0;
2068
2069 PL_op->op_ppaddr = pp_slf;
2070 PL_op->op_type = OP_CUSTOM; /* maybe we should leave it at entersub? */
2071
2072 PL_op = (OP *)&slf_restore;
2073}
2074
2075/*****************************************************************************/
2076/* PerlIO::cede */
2077
2078typedef struct
2079{
2080 PerlIOBuf base;
2081 NV next, every;
2082} PerlIOCede;
2083
2084static IV
2085PerlIOCede_pushed (pTHX_ PerlIO *f, const char *mode, SV *arg, PerlIO_funcs *tab)
2086{
2087 PerlIOCede *self = PerlIOSelf (f, PerlIOCede);
2088
2089 self->every = SvCUR (arg) ? SvNV (arg) : 0.01;
2090 self->next = nvtime () + self->every;
2091
2092 return PerlIOBuf_pushed (aTHX_ f, mode, Nullsv, tab);
2093}
2094
2095static SV *
2096PerlIOCede_getarg (pTHX_ PerlIO *f, CLONE_PARAMS *param, int flags)
2097{
2098 PerlIOCede *self = PerlIOSelf (f, PerlIOCede);
2099
2100 return newSVnv (self->every);
2101}
2102
2103static IV
2104PerlIOCede_flush (pTHX_ PerlIO *f)
2105{
2106 PerlIOCede *self = PerlIOSelf (f, PerlIOCede);
2107 double now = nvtime ();
2108
2109 if (now >= self->next)
2110 {
2111 api_cede (aTHX);
2112 self->next = now + self->every;
2113 }
2114
2115 return PerlIOBuf_flush (aTHX_ f);
2116}
2117
2118static PerlIO_funcs PerlIO_cede =
2119{
2120 sizeof(PerlIO_funcs),
2121 "cede",
2122 sizeof(PerlIOCede),
2123 PERLIO_K_DESTRUCT | PERLIO_K_RAW,
2124 PerlIOCede_pushed,
2125 PerlIOBuf_popped,
2126 PerlIOBuf_open,
2127 PerlIOBase_binmode,
2128 PerlIOCede_getarg,
2129 PerlIOBase_fileno,
2130 PerlIOBuf_dup,
2131 PerlIOBuf_read,
2132 PerlIOBuf_unread,
2133 PerlIOBuf_write,
2134 PerlIOBuf_seek,
2135 PerlIOBuf_tell,
2136 PerlIOBuf_close,
2137 PerlIOCede_flush,
2138 PerlIOBuf_fill,
2139 PerlIOBase_eof,
2140 PerlIOBase_error,
2141 PerlIOBase_clearerr,
2142 PerlIOBase_setlinebuf,
2143 PerlIOBuf_get_base,
2144 PerlIOBuf_bufsiz,
2145 PerlIOBuf_get_ptr,
2146 PerlIOBuf_get_cnt,
2147 PerlIOBuf_set_ptrcnt,
2148};
2149
2150/*****************************************************************************/
2151/* Coro::Semaphore & Coro::Signal */
2152
2153static SV *
2154coro_waitarray_new (pTHX_ int count)
2155{
2156 /* a semaphore contains a counter IV in $sem->[0] and any waiters after that */
2157 AV *av = newAV ();
2158 SV **ary;
2159
2160 /* unfortunately, building manually saves memory */
2161 Newx (ary, 2, SV *);
2162 AvALLOC (av) = ary;
2163 /*AvARRAY (av) = ary;*/
2164 SvPVX ((SV *)av) = (char *)ary; /* 5.8.8 needs this syntax instead of AvARRAY = ary */
2165 AvMAX (av) = 1;
2166 AvFILLp (av) = 0;
2167 ary [0] = newSViv (count);
2168
2169 return newRV_noinc ((SV *)av);
2170}
2171
2172/* semaphore */
2173
2174static void
2175coro_semaphore_adjust (pTHX_ AV *av, IV adjust)
2176{
2177 SV *count_sv = AvARRAY (av)[0];
2178 IV count = SvIVX (count_sv);
2179
2180 count += adjust;
2181 SvIVX (count_sv) = count;
2182
2183 /* now wake up as many waiters as are expected to lock */
2184 while (count > 0 && AvFILLp (av) > 0)
2185 {
2186 SV *cb;
2187
2188 /* swap first two elements so we can shift a waiter */
2189 AvARRAY (av)[0] = AvARRAY (av)[1];
2190 AvARRAY (av)[1] = count_sv;
2191 cb = av_shift (av);
2192
2193 if (SvOBJECT (cb))
2194 {
2195 api_ready (aTHX_ cb);
2196 --count;
2197 }
2198 else if (SvTYPE (cb) == SVt_PVCV)
2199 {
2200 dSP;
2201 PUSHMARK (SP);
2202 XPUSHs (sv_2mortal (newRV_inc ((SV *)av)));
2203 PUTBACK;
2204 call_sv (cb, G_VOID | G_DISCARD | G_EVAL | G_KEEPERR);
2205 }
2206
2207 SvREFCNT_dec (cb);
2208 }
2209}
2210
2211static void
2212coro_semaphore_on_destroy (pTHX_ struct coro *coro)
2213{
2214 /* call $sem->adjust (0) to possibly wake up some other waiters */
2215 coro_semaphore_adjust (aTHX_ (AV *)coro->slf_frame.data, 0);
2216}
2217
2218static int
2219slf_check_semaphore_down_or_wait (pTHX_ struct CoroSLF *frame, int acquire)
2220{
2221 AV *av = (AV *)frame->data;
2222 SV *count_sv = AvARRAY (av)[0];
2223
2224 /* if we are about to throw, don't actually acquire the lock, just throw */
2225 if (CORO_THROW)
2226 return 0;
2227 else if (SvIVX (count_sv) > 0)
2228 {
2229 SvSTATE_current->on_destroy = 0;
2230
2231 if (acquire)
2232 SvIVX (count_sv) = SvIVX (count_sv) - 1;
2233 else
2234 coro_semaphore_adjust (aTHX_ av, 0);
2235
2236 return 0;
2237 }
2238 else
2239 {
2240 int i;
2241 /* if we were woken up but can't down, we look through the whole */
2242 /* waiters list and only add us if we aren't in there already */
2243 /* this avoids some degenerate memory usage cases */
2244
2245 for (i = 1; i <= AvFILLp (av); ++i)
2246 if (AvARRAY (av)[i] == SvRV (coro_current))
2247 return 1;
2248
2249 av_push (av, SvREFCNT_inc (SvRV (coro_current)));
2250 return 1;
2251 }
2252}
2253
2254static int
2255slf_check_semaphore_down (pTHX_ struct CoroSLF *frame)
2256{
2257 return slf_check_semaphore_down_or_wait (aTHX_ frame, 1);
2258}
2259
2260static int
2261slf_check_semaphore_wait (pTHX_ struct CoroSLF *frame)
2262{
2263 return slf_check_semaphore_down_or_wait (aTHX_ frame, 0);
2264}
2265
2266static void
2267slf_init_semaphore_down_or_wait (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items)
2268{
2269 AV *av = (AV *)SvRV (arg [0]);
2270
2271 if (SvIVX (AvARRAY (av)[0]) > 0)
2272 {
2273 frame->data = (void *)av;
2274 frame->prepare = prepare_nop;
2275 }
2276 else
2277 {
2278 av_push (av, SvREFCNT_inc (SvRV (coro_current)));
2279
2280 frame->data = (void *)sv_2mortal (SvREFCNT_inc ((SV *)av));
2281 frame->prepare = prepare_schedule;
2282
2283 /* to avoid race conditions when a woken-up coro gets terminated */
2284 /* we arrange for a temporary on_destroy that calls adjust (0) */
2285 SvSTATE_current->on_destroy = coro_semaphore_on_destroy;
2286 }
2287}
2288
2289static void
2290slf_init_semaphore_down (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items)
2291{
2292 slf_init_semaphore_down_or_wait (aTHX_ frame, cv, arg, items);
2293 frame->check = slf_check_semaphore_down;
2294}
2295
2296static void
2297slf_init_semaphore_wait (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items)
2298{
2299 if (items >= 2)
2300 {
2301 /* callback form */
2302 AV *av = (AV *)SvRV (arg [0]);
2303 CV *cb_cv = coro_sv_2cv (arg [1]);
2304
2305 av_push (av, (SV *)SvREFCNT_inc_NN (cb_cv));
2306
2307 if (SvIVX (AvARRAY (av)[0]) > 0)
2308 coro_semaphore_adjust (aTHX_ av, 0);
2309
2310 frame->prepare = prepare_nop;
2311 frame->check = slf_check_nop;
2312 }
2313 else
2314 {
2315 slf_init_semaphore_down_or_wait (aTHX_ frame, cv, arg, items);
2316 frame->check = slf_check_semaphore_wait;
2317 }
2318}
2319
2320/* signal */
2321
2322static void
2323coro_signal_wake (pTHX_ AV *av, int count)
2324{
2325 SvIVX (AvARRAY (av)[0]) = 0;
2326
2327 /* now signal count waiters */
2328 while (count > 0 && AvFILLp (av) > 0)
2329 {
2330 SV *cb;
2331
2332 /* swap first two elements so we can shift a waiter */
2333 cb = AvARRAY (av)[0];
2334 AvARRAY (av)[0] = AvARRAY (av)[1];
2335 AvARRAY (av)[1] = cb;
2336
2337 cb = av_shift (av);
2338
2339 api_ready (aTHX_ cb);
2340 sv_setiv (cb, 0); /* signal waiter */
2341 SvREFCNT_dec (cb);
2342
2343 --count;
2344 }
2345}
2346
2347static int
2348slf_check_signal_wait (pTHX_ struct CoroSLF *frame)
2349{
2350 /* if we are about to throw, also stop waiting */
2351 return SvROK ((SV *)frame->data) && !CORO_THROW;
2352}
2353
2354static void
2355slf_init_signal_wait (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items)
2356{
2357 AV *av = (AV *)SvRV (arg [0]);
2358
2359 if (SvIVX (AvARRAY (av)[0]))
2360 {
2361 SvIVX (AvARRAY (av)[0]) = 0;
2362 frame->prepare = prepare_nop;
2363 frame->check = slf_check_nop;
2364 }
2365 else
2366 {
2367 SV *waiter = newRV_inc (SvRV (coro_current)); /* owned by signal av */
2368
2369 av_push (av, waiter);
2370
2371 frame->data = (void *)sv_2mortal (SvREFCNT_inc_NN (waiter)); /* owned by process */
2372 frame->prepare = prepare_schedule;
2373 frame->check = slf_check_signal_wait;
2374 }
2375}
2376
2377/*****************************************************************************/
2378/* Coro::AIO */
2379
2380#define CORO_MAGIC_type_aio PERL_MAGIC_ext
2381
2382/* helper storage struct */
2383struct io_state
2384{
2385 int errorno;
2386 I32 laststype; /* U16 in 5.10.0 */
2387 int laststatval;
2388 Stat_t statcache;
2389};
2390
2391static void
2392coro_aio_callback (pTHX_ CV *cv)
2393{
2394 dXSARGS;
2395 AV *state = (AV *)GENSUB_ARG;
2396 SV *coro = av_pop (state);
2397 SV *data_sv = newSV (sizeof (struct io_state));
2398
2399 av_extend (state, items);
2400
2401 sv_upgrade (data_sv, SVt_PV);
2402 SvCUR_set (data_sv, sizeof (struct io_state));
2403 SvPOK_only (data_sv);
2404
2405 {
2406 struct io_state *data = (struct io_state *)SvPVX (data_sv);
2407
2408 data->errorno = errno;
2409 data->laststype = PL_laststype;
2410 data->laststatval = PL_laststatval;
2411 data->statcache = PL_statcache;
2412 }
2413
2414 /* now build the result vector out of all the parameters and the data_sv */
2415 {
2416 int i;
2417
2418 for (i = 0; i < items; ++i)
2419 av_push (state, SvREFCNT_inc_NN (ST (i)));
2420 }
2421
2422 av_push (state, data_sv);
2423
2424 api_ready (aTHX_ coro);
2425 SvREFCNT_dec (coro);
2426 SvREFCNT_dec ((AV *)state);
2427}
2428
2429static int
2430slf_check_aio_req (pTHX_ struct CoroSLF *frame)
2431{
2432 AV *state = (AV *)frame->data;
2433
2434 /* if we are about to throw, return early */
2435 /* this does not cancel the aio request, but at least */
2436 /* it quickly returns */
2437 if (CORO_THROW)
2438 return 0;
2439
2440 /* one element that is an RV? repeat! */
2441 if (AvFILLp (state) == 0 && SvROK (AvARRAY (state)[0]))
2442 return 1;
2443
2444 /* restore status */
2445 {
2446 SV *data_sv = av_pop (state);
2447 struct io_state *data = (struct io_state *)SvPVX (data_sv);
2448
2449 errno = data->errorno;
2450 PL_laststype = data->laststype;
2451 PL_laststatval = data->laststatval;
2452 PL_statcache = data->statcache;
2453
2454 SvREFCNT_dec (data_sv);
2455 }
2456
2457 /* push result values */
2458 {
2459 dSP;
2460 int i;
2461
2462 EXTEND (SP, AvFILLp (state) + 1);
2463 for (i = 0; i <= AvFILLp (state); ++i)
2464 PUSHs (sv_2mortal (SvREFCNT_inc_NN (AvARRAY (state)[i])));
2465
2466 PUTBACK;
2467 }
2468
2469 return 0;
2470}
2471
2472static void
2473slf_init_aio_req (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items)
2474{
2475 AV *state = (AV *)sv_2mortal ((SV *)newAV ());
2476 SV *coro_hv = SvRV (coro_current);
2477 struct coro *coro = SvSTATE_hv (coro_hv);
2478
2479 /* put our coroutine id on the state arg */
2480 av_push (state, SvREFCNT_inc_NN (coro_hv));
2481
2482 /* first see whether we have a non-zero priority and set it as AIO prio */
2483 if (coro->prio)
2484 {
2485 dSP;
2486
2487 static SV *prio_cv;
2488 static SV *prio_sv;
2489
2490 if (expect_false (!prio_cv))
2491 {
2492 prio_cv = (SV *)get_cv ("IO::AIO::aioreq_pri", 0);
2493 prio_sv = newSViv (0);
2494 }
2495
2496 PUSHMARK (SP);
2497 sv_setiv (prio_sv, coro->prio);
2498 XPUSHs (prio_sv);
2499
2500 PUTBACK;
2501 call_sv (prio_cv, G_VOID | G_DISCARD);
2502 }
2503
2504 /* now call the original request */
2505 {
2506 dSP;
2507 CV *req = (CV *)CORO_MAGIC_NN ((SV *)cv, CORO_MAGIC_type_aio)->mg_obj;
2508 int i;
2509
2510 PUSHMARK (SP);
2511
2512 /* first push all args to the stack */
2513 EXTEND (SP, items + 1);
2514
2515 for (i = 0; i < items; ++i)
2516 PUSHs (arg [i]);
2517
2518 /* now push the callback closure */
2519 PUSHs (sv_2mortal (gensub (aTHX_ coro_aio_callback, (void *)SvREFCNT_inc_NN ((SV *)state))));
2520
2521 /* now call the AIO function - we assume our request is uncancelable */
2522 PUTBACK;
2523 call_sv ((SV *)req, G_VOID | G_DISCARD);
2524 }
2525
2526 /* now that the requets is going, we loop toll we have a result */
2527 frame->data = (void *)state;
2528 frame->prepare = prepare_schedule;
2529 frame->check = slf_check_aio_req;
2530}
2531
2532static void
2533coro_aio_req_xs (pTHX_ CV *cv)
2534{
2535 dXSARGS;
2536
2537 CORO_EXECUTE_SLF_XS (slf_init_aio_req);
2538
2539 XSRETURN_EMPTY;
2540}
2541
2542/*****************************************************************************/
2543
2544MODULE = Coro::State PACKAGE = Coro::State PREFIX = api_
2545
2546PROTOTYPES: DISABLE
2547
2548BOOT:
2549{
2550#ifdef USE_ITHREADS
2551# if CORO_PTHREAD
2552 coro_thx = PERL_GET_CONTEXT;
2553# endif
2554#endif
2555 BOOT_PAGESIZE;
2556
2557 irsgv = gv_fetchpv ("/" , GV_ADD|GV_NOTQUAL, SVt_PV);
2558 stdoutgv = gv_fetchpv ("STDOUT", GV_ADD|GV_NOTQUAL, SVt_PVIO);
2559
2560 orig_sigelem_get = PL_vtbl_sigelem.svt_get; PL_vtbl_sigelem.svt_get = coro_sigelem_get;
2561 orig_sigelem_set = PL_vtbl_sigelem.svt_set; PL_vtbl_sigelem.svt_set = coro_sigelem_set;
2562 orig_sigelem_clr = PL_vtbl_sigelem.svt_clear; PL_vtbl_sigelem.svt_clear = coro_sigelem_clr;
2563
2564 hv_sig = coro_get_hv (aTHX_ "SIG", TRUE);
2565 rv_diehook = newRV_inc ((SV *)gv_fetchpv ("Coro::State::diehook" , 0, SVt_PVCV));
2566 rv_warnhook = newRV_inc ((SV *)gv_fetchpv ("Coro::State::warnhook", 0, SVt_PVCV));
2567
2568 coro_state_stash = gv_stashpv ("Coro::State", TRUE);
2569
2570 newCONSTSUB (coro_state_stash, "CC_TRACE" , newSViv (CC_TRACE));
2571 newCONSTSUB (coro_state_stash, "CC_TRACE_SUB" , newSViv (CC_TRACE_SUB));
2572 newCONSTSUB (coro_state_stash, "CC_TRACE_LINE", newSViv (CC_TRACE_LINE));
2573 newCONSTSUB (coro_state_stash, "CC_TRACE_ALL" , newSViv (CC_TRACE_ALL));
2574
2575 main_mainstack = PL_mainstack;
2576 main_top_env = PL_top_env;
2577
2578 while (main_top_env->je_prev)
2579 main_top_env = main_top_env->je_prev;
2580
2581 {
2582 SV *slf = sv_2mortal (newSViv (PTR2IV (pp_slf)));
2583
2584 if (!PL_custom_op_names) PL_custom_op_names = newHV ();
2585 hv_store_ent (PL_custom_op_names, slf,
2586 newSVpv ("coro_slf", 0), 0);
2587
2588 if (!PL_custom_op_descs) PL_custom_op_descs = newHV ();
2589 hv_store_ent (PL_custom_op_descs, slf,
2590 newSVpv ("coro schedule like function", 0), 0);
2591 }
2592
2593 coroapi.ver = CORO_API_VERSION;
2594 coroapi.rev = CORO_API_REVISION;
2595
2596 coroapi.transfer = api_transfer;
2597
2598 coroapi.sv_state = SvSTATE_;
2599 coroapi.execute_slf = api_execute_slf;
2600 coroapi.prepare_nop = prepare_nop;
2601 coroapi.prepare_schedule = prepare_schedule;
2602 coroapi.prepare_cede = prepare_cede;
2603 coroapi.prepare_cede_notself = prepare_cede_notself;
2604
2605 {
2606 SV **svp = hv_fetch (PL_modglobal, "Time::NVtime", 12, 0);
2607
2608 if (!svp) croak ("Time::HiRes is required");
2609 if (!SvIOK (*svp)) croak ("Time::NVtime isn't a function pointer");
2610
2611 nvtime = INT2PTR (double (*)(), SvIV (*svp));
2612 }
2613
2614 assert (("PRIO_NORMAL must be 0", !PRIO_NORMAL));
2615}
2616
2617SV *
2618new (char *klass, ...)
2619 CODE:
2620{
2621 struct coro *coro;
2622 MAGIC *mg;
2623 HV *hv;
2624 CV *cb;
2625 int i;
2626
2627 if (items > 1)
2628 {
2629 cb = coro_sv_2cv (ST (1));
2630
2631 if (CvISXSUB (cb))
2632 croak ("Coro::State doesn't support XS functions as coroutine start, caught");
2633
2634 if (!CvROOT (cb))
2635 croak ("Coro::State doesn't support autoloaded or undefined functions as coroutine start, caught");
2636 }
2637
2638 Newz (0, coro, 1, struct coro);
2639 coro->args = newAV ();
2640 coro->flags = CF_NEW;
2641
2642 if (coro_first) coro_first->prev = coro;
2643 coro->next = coro_first;
2644 coro_first = coro;
2645
2646 coro->hv = hv = newHV ();
2647 mg = sv_magicext ((SV *)hv, 0, CORO_MAGIC_type_state, &coro_state_vtbl, (char *)coro, 0);
2648 mg->mg_flags |= MGf_DUP;
2649 RETVAL = sv_bless (newRV_noinc ((SV *)hv), gv_stashpv (klass, 1));
2650
2651 if (items > 1)
2652 {
2653 coro->startcv = SvREFCNT_inc_NN (cb);
2654
2655 av_extend (coro->args, items - 1);
2656 for (i = 2; i < items; i++)
2657 av_push (coro->args, newSVsv (ST (i)));
2658 }
2659}
2660 OUTPUT:
2661 RETVAL
2662
2663void
2664transfer (...)
2665 PROTOTYPE: $$
2666 CODE:
2667 CORO_EXECUTE_SLF_XS (slf_init_transfer);
2668
2669bool
2670_destroy (SV *coro_sv)
2671 CODE:
2672 RETVAL = coro_state_destroy (aTHX_ SvSTATE (coro_sv));
2673 OUTPUT:
2674 RETVAL
2675
2676void
2677_exit (int code)
2678 PROTOTYPE: $
2679 CODE:
2680 _exit (code);
2681
2682int
2683cctx_stacksize (int new_stacksize = 0)
2684 PROTOTYPE: ;$
2685 CODE:
2686 RETVAL = cctx_stacksize;
2687 if (new_stacksize)
2688 {
2689 cctx_stacksize = new_stacksize;
2690 ++cctx_gen;
2691 }
2692 OUTPUT:
2693 RETVAL
2694
2695int
2696cctx_max_idle (int max_idle = 0)
2697 PROTOTYPE: ;$
2698 CODE:
2699 RETVAL = cctx_max_idle;
2700 if (max_idle > 1)
2701 cctx_max_idle = max_idle;
2702 OUTPUT:
2703 RETVAL
2704
2705int
2706cctx_count ()
2707 PROTOTYPE:
2708 CODE:
2709 RETVAL = cctx_count;
2710 OUTPUT:
2711 RETVAL
2712
2713int
2714cctx_idle ()
2715 PROTOTYPE:
2716 CODE:
2717 RETVAL = cctx_idle;
2718 OUTPUT:
2719 RETVAL
2720
2721void
2722list ()
2723 PROTOTYPE:
2724 PPCODE:
2725{
2726 struct coro *coro;
2727 for (coro = coro_first; coro; coro = coro->next)
2728 if (coro->hv)
2729 XPUSHs (sv_2mortal (newRV_inc ((SV *)coro->hv)));
2730}
2731
2732void
2733call (Coro::State coro, SV *coderef)
2734 ALIAS:
2735 eval = 1
2736 CODE:
2737{
2738 if (coro->mainstack && ((coro->flags & CF_RUNNING) || coro->slot))
2739 {
2740 struct coro temp;
2741
2742 if (!(coro->flags & CF_RUNNING))
235 { 2743 {
236 /* I never used formats, so how should I know how these are implemented? */ 2744 PUTBACK;
237 /* my bold guess is as a simple, plain sub... */ 2745 save_perl (aTHX_ &temp);
238 croak ("CXt_FORMAT not yet handled. Don't switch coroutines from within formats"); 2746 load_perl (aTHX_ coro);
2747 }
2748
2749 {
2750 dSP;
2751 ENTER;
2752 SAVETMPS;
2753 PUTBACK;
2754 PUSHSTACK;
2755 PUSHMARK (SP);
2756
2757 if (ix)
2758 eval_sv (coderef, 0);
2759 else
2760 call_sv (coderef, G_KEEPERR | G_EVAL | G_VOID | G_DISCARD);
2761
2762 POPSTACK;
2763 SPAGAIN;
2764 FREETMPS;
2765 LEAVE;
2766 PUTBACK;
2767 }
2768
2769 if (!(coro->flags & CF_RUNNING))
2770 {
2771 save_perl (aTHX_ coro);
2772 load_perl (aTHX_ &temp);
2773 SPAGAIN;
239 } 2774 }
240 } 2775 }
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} 2776}
281 2777
282static void 2778SV *
283LOAD(pTHX_ Coro__State c) 2779is_ready (Coro::State coro)
284{ 2780 PROTOTYPE: $
285 PL_dowarn = c->dowarn; 2781 ALIAS:
286 GvAV (PL_defgv) = c->defav; 2782 is_ready = CF_READY
287 PL_curstackinfo = c->curstackinfo; 2783 is_running = CF_RUNNING
288 PL_curstack = c->curstack; 2784 is_new = CF_NEW
289 PL_mainstack = c->mainstack; 2785 is_destroyed = CF_DESTROYED
290 PL_stack_sp = c->stack_sp; 2786 CODE:
291 PL_op = c->op; 2787 RETVAL = boolSV (coro->flags & ix);
292 PL_curpad = c->curpad; 2788 OUTPUT:
293 PL_stack_base = c->stack_base; 2789 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 2790
2791void
2792throw (Coro::State self, SV *throw = &PL_sv_undef)
2793 PROTOTYPE: $;$
2794 CODE:
2795{
2796 struct coro *current = SvSTATE_current;
2797 SV **throwp = self == current ? &CORO_THROW : &self->except;
2798 SvREFCNT_dec (*throwp);
2799 *throwp = SvOK (throw) ? newSVsv (throw) : 0;
2800}
2801
2802void
2803api_trace (SV *coro, int flags = CC_TRACE | CC_TRACE_SUB)
2804 PROTOTYPE: $;$
2805 C_ARGS: aTHX_ coro, flags
2806
2807SV *
2808has_cctx (Coro::State coro)
2809 PROTOTYPE: $
2810 CODE:
2811 RETVAL = boolSV (!!coro->cctx);
2812 OUTPUT:
2813 RETVAL
2814
2815int
2816is_traced (Coro::State coro)
2817 PROTOTYPE: $
2818 CODE:
2819 RETVAL = (coro->cctx ? coro->cctx->flags : 0) & CC_TRACE_ALL;
2820 OUTPUT:
2821 RETVAL
2822
2823UV
2824rss (Coro::State coro)
2825 PROTOTYPE: $
2826 ALIAS:
2827 usecount = 1
2828 CODE:
2829 switch (ix)
313 { 2830 {
314 dSP; 2831 case 0: RETVAL = coro_rss (aTHX_ coro); break;
315 CV *cv; 2832 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 } 2833 }
2834 OUTPUT:
2835 RETVAL
331 2836
332 PUTBACK; 2837void
333 } 2838force_cctx ()
334} 2839 PROTOTYPE:
2840 CODE:
2841 SvSTATE_current->cctx->idle_sp = 0;
335 2842
336/* this is an EXACT copy of S_nuke_stacks in perl.c, which is unfortunately static */ 2843void
337STATIC void 2844swap_defsv (Coro::State self)
338destroy_stacks(pTHX) 2845 PROTOTYPE: $
339{ 2846 ALIAS:
340 /* die does this while calling POPSTACK, but I just don't see why. */ 2847 swap_defav = 1
341 dounwind(-1); 2848 CODE:
2849 if (!self->slot)
2850 croak ("cannot swap state with coroutine that has no saved state,");
2851 else
2852 {
2853 SV **src = ix ? (SV **)&GvAV (PL_defgv) : &GvSV (PL_defgv);
2854 SV **dst = ix ? (SV **)&self->slot->defav : (SV **)&self->slot->defsv;
342 2855
343 /* is this ugly, I ask? */ 2856 SV *tmp = *src; *src = *dst; *dst = tmp;
344 while (PL_scopestack_ix) 2857 }
345 LEAVE;
346 2858
347 while (PL_curstackinfo->si_next)
348 PL_curstackinfo = PL_curstackinfo->si_next;
349 2859
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 2860MODULE = Coro::State PACKAGE = Coro
383
384PROTOTYPES: ENABLE
385 2861
386BOOT: 2862BOOT:
387 if (!padlist_cache) 2863{
388 padlist_cache = newHV (); 2864 int i;
389 2865
390Coro::State 2866 av_async_pool = coro_get_av (aTHX_ "Coro::async_pool", TRUE);
391_newprocess(args) 2867 sv_pool_rss = coro_get_sv (aTHX_ "Coro::POOL_RSS" , TRUE);
392 SV * args 2868 sv_pool_size = coro_get_sv (aTHX_ "Coro::POOL_SIZE" , TRUE);
2869
2870 coro_current = coro_get_sv (aTHX_ "Coro::current", FALSE);
2871 SvREADONLY_on (coro_current);
2872
2873 coro_stash = gv_stashpv ("Coro", TRUE);
2874
2875 newCONSTSUB (coro_stash, "PRIO_MAX", newSViv (PRIO_MAX));
2876 newCONSTSUB (coro_stash, "PRIO_HIGH", newSViv (PRIO_HIGH));
2877 newCONSTSUB (coro_stash, "PRIO_NORMAL", newSViv (PRIO_NORMAL));
2878 newCONSTSUB (coro_stash, "PRIO_LOW", newSViv (PRIO_LOW));
2879 newCONSTSUB (coro_stash, "PRIO_IDLE", newSViv (PRIO_IDLE));
2880 newCONSTSUB (coro_stash, "PRIO_MIN", newSViv (PRIO_MIN));
2881
2882 for (i = PRIO_MAX - PRIO_MIN + 1; i--; )
2883 coro_ready[i] = newAV ();
2884
2885 {
2886 SV *sv = coro_get_sv (aTHX_ "Coro::API", TRUE);
2887
2888 coroapi.schedule = api_schedule;
2889 coroapi.cede = api_cede;
2890 coroapi.cede_notself = api_cede_notself;
2891 coroapi.ready = api_ready;
2892 coroapi.is_ready = api_is_ready;
2893 coroapi.nready = coro_nready;
2894 coroapi.current = coro_current;
2895
2896 /*GCoroAPI = &coroapi;*/
2897 sv_setiv (sv, (IV)&coroapi);
2898 SvREADONLY_on (sv);
2899 }
2900}
2901
2902void
2903schedule (...)
2904 CODE:
2905 CORO_EXECUTE_SLF_XS (slf_init_schedule);
2906
2907void
2908cede (...)
2909 CODE:
2910 CORO_EXECUTE_SLF_XS (slf_init_cede);
2911
2912void
2913cede_notself (...)
2914 CODE:
2915 CORO_EXECUTE_SLF_XS (slf_init_cede_notself);
2916
2917void
2918_set_current (SV *current)
393 PROTOTYPE: $ 2919 PROTOTYPE: $
2920 CODE:
2921 SvREFCNT_dec (SvRV (coro_current));
2922 SvRV_set (coro_current, SvREFCNT_inc_NN (SvRV (current)));
2923
2924void
2925_set_readyhook (SV *hook)
2926 PROTOTYPE: $
394 CODE: 2927 CODE:
395 Coro__State coro; 2928 SvREFCNT_dec (coro_readyhook);
2929 coro_readyhook = SvOK (hook) ? newSVsv (hook) : 0;
396 2930
397 if (!SvROK (args) || SvTYPE (SvRV (args)) != SVt_PVAV) 2931int
398 croak ("Coro::State::newprocess expects an arrayref"); 2932prio (Coro::State coro, int newprio = 0)
2933 PROTOTYPE: $;$
2934 ALIAS:
2935 nice = 1
399 2936 CODE:
400 New (0, coro, 1, struct coro); 2937{
401
402 coro->mainstack = 0; /* actual work is done inside transfer */
403 coro->args = (AV *)SvREFCNT_inc (SvRV (args));
404
405 RETVAL = coro; 2938 RETVAL = coro->prio;
2939
2940 if (items > 1)
2941 {
2942 if (ix)
2943 newprio = coro->prio - newprio;
2944
2945 if (newprio < PRIO_MIN) newprio = PRIO_MIN;
2946 if (newprio > PRIO_MAX) newprio = PRIO_MAX;
2947
2948 coro->prio = newprio;
2949 }
2950}
2951 OUTPUT:
2952 RETVAL
2953
2954SV *
2955ready (SV *self)
2956 PROTOTYPE: $
2957 CODE:
2958 RETVAL = boolSV (api_ready (aTHX_ self));
2959 OUTPUT:
2960 RETVAL
2961
2962int
2963nready (...)
2964 PROTOTYPE:
2965 CODE:
2966 RETVAL = coro_nready;
2967 OUTPUT:
2968 RETVAL
2969
2970# for async_pool speedup
2971void
2972_pool_1 (SV *cb)
2973 CODE:
2974{
2975 HV *hv = (HV *)SvRV (coro_current);
2976 struct coro *coro = SvSTATE_hv ((SV *)hv);
2977 AV *defav = GvAV (PL_defgv);
2978 SV *invoke = hv_delete (hv, "_invoke", sizeof ("_invoke") - 1, 0);
2979 AV *invoke_av;
2980 int i, len;
2981
2982 if (!invoke)
2983 {
2984 SV *old = PL_diehook;
2985 PL_diehook = 0;
2986 SvREFCNT_dec (old);
2987 croak ("\3async_pool terminate\2\n");
2988 }
2989
2990 SvREFCNT_dec (coro->saved_deffh);
2991 coro->saved_deffh = SvREFCNT_inc_NN ((SV *)PL_defoutgv);
2992
2993 hv_store (hv, "desc", sizeof ("desc") - 1,
2994 newSVpvn ("[async_pool]", sizeof ("[async_pool]") - 1), 0);
2995
2996 invoke_av = (AV *)SvRV (invoke);
2997 len = av_len (invoke_av);
2998
2999 sv_setsv (cb, AvARRAY (invoke_av)[0]);
3000
3001 if (len > 0)
3002 {
3003 av_fill (defav, len - 1);
3004 for (i = 0; i < len; ++i)
3005 av_store (defav, i, SvREFCNT_inc_NN (AvARRAY (invoke_av)[i + 1]));
3006 }
3007}
3008
3009void
3010_pool_2 (SV *cb)
3011 CODE:
3012{
3013 HV *hv = (HV *)SvRV (coro_current);
3014 struct coro *coro = SvSTATE_hv ((SV *)hv);
3015
3016 sv_setsv (cb, &PL_sv_undef);
3017
3018 SvREFCNT_dec ((SV *)PL_defoutgv); PL_defoutgv = (GV *)coro->saved_deffh;
3019 coro->saved_deffh = 0;
3020
3021 if (coro_rss (aTHX_ coro) > SvUV (sv_pool_rss)
3022 || av_len (av_async_pool) + 1 >= SvIV (sv_pool_size))
3023 {
3024 SV *old = PL_diehook;
3025 PL_diehook = 0;
3026 SvREFCNT_dec (old);
3027 croak ("\3async_pool terminate\2\n");
3028 }
3029
3030 av_clear (GvAV (PL_defgv));
3031 hv_store (hv, "desc", sizeof ("desc") - 1,
3032 newSVpvn ("[async_pool idle]", sizeof ("[async_pool idle]") - 1), 0);
3033
3034 coro->prio = 0;
3035
3036 if (coro->cctx && (coro->cctx->flags & CC_TRACE))
3037 api_trace (aTHX_ coro_current, 0);
3038
3039 av_push (av_async_pool, newSVsv (coro_current));
3040}
3041
3042SV *
3043rouse_cb ()
3044 PROTOTYPE:
3045 CODE:
3046 RETVAL = coro_new_rouse_cb (aTHX);
3047 OUTPUT:
3048 RETVAL
3049
3050void
3051rouse_wait (...)
3052 PROTOTYPE: ;$
3053 PPCODE:
3054 CORO_EXECUTE_SLF_XS (slf_init_rouse_wait);
3055
3056
3057MODULE = Coro::State PACKAGE = PerlIO::cede
3058
3059BOOT:
3060 PerlIO_define_layer (aTHX_ &PerlIO_cede);
3061
3062
3063MODULE = Coro::State PACKAGE = Coro::Semaphore
3064
3065SV *
3066new (SV *klass, SV *count = 0)
3067 CODE:
3068 RETVAL = sv_bless (
3069 coro_waitarray_new (aTHX_ count && SvOK (count) ? SvIV (count) : 1),
3070 GvSTASH (CvGV (cv))
3071 );
3072 OUTPUT:
3073 RETVAL
3074
3075# helper for Coro::Channel
3076SV *
3077_alloc (int count)
3078 CODE:
3079 RETVAL = coro_waitarray_new (aTHX_ count);
3080 OUTPUT:
3081 RETVAL
3082
3083SV *
3084count (SV *self)
3085 CODE:
3086 RETVAL = newSVsv (AvARRAY ((AV *)SvRV (self))[0]);
3087 OUTPUT:
3088 RETVAL
3089
3090void
3091up (SV *self, int adjust = 1)
3092 ALIAS:
3093 adjust = 1
3094 CODE:
3095 coro_semaphore_adjust (aTHX_ (AV *)SvRV (self), ix ? adjust : 1);
3096
3097void
3098down (...)
3099 CODE:
3100 CORO_EXECUTE_SLF_XS (slf_init_semaphore_down);
3101
3102void
3103wait (...)
3104 CODE:
3105 CORO_EXECUTE_SLF_XS (slf_init_semaphore_wait);
3106
3107void
3108try (SV *self)
3109 PPCODE:
3110{
3111 AV *av = (AV *)SvRV (self);
3112 SV *count_sv = AvARRAY (av)[0];
3113 IV count = SvIVX (count_sv);
3114
3115 if (count > 0)
3116 {
3117 --count;
3118 SvIVX (count_sv) = count;
3119 XSRETURN_YES;
3120 }
3121 else
3122 XSRETURN_NO;
3123}
3124
3125void
3126waiters (SV *self)
3127 PPCODE:
3128{
3129 AV *av = (AV *)SvRV (self);
3130 int wcount = AvFILLp (av) + 1 - 1;
3131
3132 if (GIMME_V == G_SCALAR)
3133 XPUSHs (sv_2mortal (newSViv (wcount)));
3134 else
3135 {
3136 int i;
3137 EXTEND (SP, wcount);
3138 for (i = 1; i <= wcount; ++i)
3139 PUSHs (sv_2mortal (newRV_inc (AvARRAY (av)[i])));
3140 }
3141}
3142
3143MODULE = Coro::State PACKAGE = Coro::Signal
3144
3145SV *
3146new (SV *klass)
3147 CODE:
3148 RETVAL = sv_bless (
3149 coro_waitarray_new (aTHX_ 0),
3150 GvSTASH (CvGV (cv))
3151 );
406 OUTPUT: 3152 OUTPUT:
407 RETVAL 3153 RETVAL
408 3154
409void 3155void
410transfer(prev,next) 3156wait (...)
411 Coro::State_or_hashref prev
412 Coro::State_or_hashref next
413 CODE: 3157 CODE:
3158 CORO_EXECUTE_SLF_XS (slf_init_signal_wait);
414 3159
415 if (prev != next) 3160void
3161broadcast (SV *self)
3162 CODE:
3163{
3164 AV *av = (AV *)SvRV (self);
3165 coro_signal_wake (aTHX_ av, AvFILLp (av));
3166}
3167
3168void
3169send (SV *self)
3170 CODE:
3171{
3172 AV *av = (AV *)SvRV (self);
3173
3174 if (AvFILLp (av))
3175 coro_signal_wake (aTHX_ av, 1);
3176 else
3177 SvIVX (AvARRAY (av)[0]) = 1; /* remember the signal */
3178}
3179
3180IV
3181awaited (SV *self)
3182 CODE:
3183 RETVAL = AvFILLp ((AV *)SvRV (self)) + 1 - 1;
3184 OUTPUT:
3185 RETVAL
3186
3187
3188MODULE = Coro::State PACKAGE = Coro::AnyEvent
3189
3190BOOT:
3191 sv_activity = coro_get_sv (aTHX_ "Coro::AnyEvent::ACTIVITY", TRUE);
3192
3193void
3194_schedule (...)
3195 CODE:
3196{
3197 static int incede;
3198
3199 api_cede_notself (aTHX);
3200
3201 ++incede;
3202 while (coro_nready >= incede && api_cede (aTHX))
3203 ;
3204
3205 sv_setsv (sv_activity, &PL_sv_undef);
3206 if (coro_nready >= incede)
416 { 3207 {
3208 PUSHMARK (SP);
417 PUTBACK; 3209 PUTBACK;
418 SAVE (aTHX_ prev); 3210 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 } 3211 }
464 3212
3213 --incede;
3214}
3215
3216
3217MODULE = Coro::State PACKAGE = Coro::AIO
3218
465void 3219void
466DESTROY(coro) 3220_register (char *target, char *proto, SV *req)
467 Coro::State coro 3221 CODE:
468 CODE: 3222{
3223 CV *req_cv = coro_sv_2cv (req);
3224 /* newXSproto doesn't return the CV on 5.8 */
3225 CV *slf_cv = newXS (target, coro_aio_req_xs, __FILE__);
3226 sv_setpv ((SV *)slf_cv, proto);
3227 sv_magicext ((SV *)slf_cv, (SV *)req_cv, CORO_MAGIC_type_aio, 0, 0, 0);
3228}
469 3229
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