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.4 by root, Tue Jul 17 02:21:56 2001 UTC vs.
Revision 1.393 by root, Fri Apr 29 17:38:56 2011 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines