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.474 by root, Tue Aug 14 15:46:03 2018 UTC vs.
Revision 1.478 by root, Mon Mar 16 11:12:52 2020 UTC

283 int usecount; /* number of transfers to this coro */ 283 int usecount; /* number of transfers to this coro */
284 284
285 /* coro process data */ 285 /* coro process data */
286 int prio; 286 int prio;
287 SV *except; /* exception to be thrown */ 287 SV *except; /* exception to be thrown */
288 SV *rouse_cb; /* last rouse callback */ 288 SV *rouse_cb; /* most recently created rouse callback */
289 AV *on_destroy; /* callbacks or coros to notify on destroy */ 289 AV *on_destroy; /* callbacks or coros to notify on destroy */
290 AV *status; /* the exit status list */ 290 AV *status; /* the exit status list */
291 291
292 /* async_pool */ 292 /* async_pool */
293 SV *saved_deffh; 293 SV *saved_deffh;
1859 1859
1860static int ecb_cold 1860static int ecb_cold
1861coro_state_dup (pTHX_ MAGIC *mg, CLONE_PARAMS *params) 1861coro_state_dup (pTHX_ MAGIC *mg, CLONE_PARAMS *params)
1862{ 1862{
1863 /* called when perl clones the current process the slow way (windows process emulation) */ 1863 /* called when perl clones the current process the slow way (windows process emulation) */
1864 /* WE SIMply nuke the pointers in the copy, causing perl to croak */ 1864 /* we simply nuke the pointers in the copy, causing perl to croak */
1865 mg->mg_ptr = 0; 1865 mg->mg_ptr = 0;
1866 mg->mg_virtual = 0; 1866 mg->mg_virtual = 0;
1867 1867
1868 return 0; 1868 return 0;
1869} 1869}
2481 2481
2482 if (ecb_expect_false (coro->cctx) && ecb_expect_false (coro->cctx->flags & CC_TRACE)) 2482 if (ecb_expect_false (coro->cctx) && ecb_expect_false (coro->cctx->flags & CC_TRACE))
2483 api_trace (aTHX_ coro_current, 0); 2483 api_trace (aTHX_ coro_current, 0);
2484 2484
2485 frame->prepare = prepare_schedule; 2485 frame->prepare = prepare_schedule;
2486 av_push (av_async_pool, SvREFCNT_inc (hv)); 2486 av_push (av_async_pool, SvREFCNT_inc_NN (hv));
2487 } 2487 }
2488 } 2488 }
2489 else 2489 else
2490 { 2490 {
2491 /* first iteration, simply fall through */ 2491 /* first iteration, simply fall through */
2504static void 2504static void
2505coro_rouse_callback (pTHX_ CV *cv) 2505coro_rouse_callback (pTHX_ CV *cv)
2506{ 2506{
2507 dXSARGS; 2507 dXSARGS;
2508 SV *data = (SV *)S_GENSUB_ARG; 2508 SV *data = (SV *)S_GENSUB_ARG;
2509 SV *coro = SvRV (data);
2509 2510
2511 /* data starts being either undef or a coro, and is replaced by the results when done */
2510 if (SvTYPE (SvRV (data)) != SVt_PVAV) 2512 if (SvTYPE (coro) != SVt_PVAV)
2511 { 2513 {
2512 /* first call, set args */ 2514 /* first call, set args */
2513 SV *coro = SvRV (data);
2514 AV *av = newAV ();
2515 2515
2516 SvRV_set (data, (SV *)av); 2516 assert (&ST (0) < &ST (1)); /* ensure the stack is in the order we expect it to be */
2517 SvRV_set (data, (SV *)av_make (items, &ST (0))); /* av_make copies the SVs */
2517 2518
2518 /* better take a full copy of the arguments */ 2519 if (coro != &PL_sv_undef)
2519 while (items--) 2520 {
2520 av_store (av, items, newSVsv (ST (items)));
2521
2522 api_ready (aTHX_ coro); 2521 api_ready (aTHX_ coro);
2523 SvREFCNT_dec (coro); 2522 SvREFCNT_dec_NN (coro);
2523 }
2524 } 2524 }
2525 2525
2526 XSRETURN_EMPTY; 2526 XSRETURN_EMPTY;
2527} 2527}
2528 2528
2545 2545
2546 EXTEND (SP, AvFILLp (av) + 1); 2546 EXTEND (SP, AvFILLp (av) + 1);
2547 for (i = 0; i <= AvFILLp (av); ++i) 2547 for (i = 0; i <= AvFILLp (av); ++i)
2548 PUSHs (sv_2mortal (AvARRAY (av)[i])); 2548 PUSHs (sv_2mortal (AvARRAY (av)[i]));
2549 2549
2550 /* we have stolen the elements, so set length to zero and free */ 2550 /* we have stolen the elements, make it unreal and free */
2551 AvFILLp (av) = -1; 2551 AvREAL_off (av);
2552 av_undef (av); 2552 av_undef (av);
2553 2553
2554 PUTBACK; 2554 PUTBACK;
2555 } 2555 }
2556 2556
2581 croak ("Coro::rouse_wait called with illegal callback argument,"); 2581 croak ("Coro::rouse_wait called with illegal callback argument,");
2582 2582
2583 { 2583 {
2584 CV *cv = (CV *)SvRV (cb); /* for S_GENSUB_ARG */ 2584 CV *cv = (CV *)SvRV (cb); /* for S_GENSUB_ARG */
2585 SV *data = (SV *)S_GENSUB_ARG; 2585 SV *data = (SV *)S_GENSUB_ARG;
2586 int data_ready = SvTYPE (SvRV (data)) == SVt_PVAV;
2587
2588 /* if there is no data, we need to store the current coro in the reference so we can be woken up */
2589 if (!data_ready)
2590 if (SvRV (data) != &PL_sv_undef)
2591 croak ("Coro::rouse_wait was called on a calback that is already being waited for - only one thread can wait for a rouse callback, caught");
2592 else
2593 SvRV_set (data, SvREFCNT_inc_NN (SvRV (coro_current)));
2586 2594
2587 frame->data = (void *)data; 2595 frame->data = (void *)data;
2588 frame->prepare = SvTYPE (SvRV (data)) == SVt_PVAV ? prepare_nop : prepare_schedule; 2596 frame->prepare = data_ready ? prepare_nop : prepare_schedule;
2589 frame->check = slf_check_rouse_wait; 2597 frame->check = slf_check_rouse_wait;
2590 } 2598 }
2591} 2599}
2592 2600
2593static SV * 2601static SV *
2594coro_new_rouse_cb (pTHX) 2602coro_new_rouse_cb (pTHX)
2595{ 2603{
2596 HV *hv = (HV *)SvRV (coro_current); 2604 HV *hv = (HV *)SvRV (coro_current);
2597 struct coro *coro = SvSTATE_hv (hv); 2605 struct coro *coro = SvSTATE_hv (hv);
2598 SV *data = newRV_inc ((SV *)hv); 2606 SV *data = newRV_noinc (&PL_sv_undef);
2599 SV *cb = s_gensub (aTHX_ coro_rouse_callback, (void *)data); 2607 SV *cb = s_gensub (aTHX_ coro_rouse_callback, (void *)data);
2600 2608
2601 sv_magicext (SvRV (cb), data, CORO_MAGIC_type_rouse, 0, 0, 0); 2609 sv_magicext (SvRV (cb), data, CORO_MAGIC_type_rouse, 0, 0, 0);
2602 SvREFCNT_dec (data); /* magicext increases the refcount */ 2610 SvREFCNT_dec_NN (data); /* magicext increases the refcount */
2603 2611
2604 SvREFCNT_dec (coro->rouse_cb); 2612 SvREFCNT_dec (coro->rouse_cb);
2605 coro->rouse_cb = SvREFCNT_inc_NN (cb); 2613 coro->rouse_cb = SvREFCNT_inc_NN (cb);
2606 2614
2607 return cb; 2615 return cb;
3829call (Coro::State coro, SV *coderef) 3837call (Coro::State coro, SV *coderef)
3830 ALIAS: 3838 ALIAS:
3831 eval = 1 3839 eval = 1
3832 CODE: 3840 CODE:
3833{ 3841{
3842 struct coro *current = SvSTATE_current;
3843
3834 if (coro->mainstack && ((coro->flags & CF_RUNNING) || coro->slot)) 3844 if ((coro == current) || (coro->mainstack && ((coro->flags & CF_RUNNING) || coro->slot)))
3835 { 3845 {
3836 struct coro *current = SvSTATE_current;
3837 struct CoroSLF slf_save; 3846 struct CoroSLF slf_save;
3838 3847
3839 if (current != coro) 3848 if (current != coro)
3840 { 3849 {
3841 PUTBACK; 3850 PUTBACK;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines