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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines