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.477 by root, Sat Feb 29 21:40:22 2020 UTC vs.
Revision 1.480 by root, Fri Jun 25 01:13:21 2021 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;
1309 1309
1310 assert (("FATAL: tried to destroy currently running coroutine", coro->mainstack != PL_mainstack)); 1310 assert (("FATAL: tried to destroy currently running coroutine", coro->mainstack != PL_mainstack));
1311 1311
1312 save_perl (aTHX_ current); 1312 save_perl (aTHX_ current);
1313 1313
1314 /* this will cause transfer_check to croak on block*/ 1314 /* this will cause transfer_check to croak on block */
1315 SvRV_set (coro_current, (SV *)coro->hv); 1315 SvRV_set (coro_current, (SV *)coro->hv);
1316 1316
1317 load_perl (aTHX_ coro); 1317 load_perl (aTHX_ coro);
1318 1318
1319 /* restore swapped sv's */ 1319 /* restore swapped sv's */
1844 1844
1845static int 1845static int
1846coro_state_free (pTHX_ SV *sv, MAGIC *mg) 1846coro_state_free (pTHX_ SV *sv, MAGIC *mg)
1847{ 1847{
1848 struct coro *coro = (struct coro *)mg->mg_ptr; 1848 struct coro *coro = (struct coro *)mg->mg_ptr;
1849
1850 coro_state_destroy (aTHX_ coro);
1849 mg->mg_ptr = 0; 1851 mg->mg_ptr = 0;
1850 1852
1851 coro_state_destroy (aTHX_ coro);
1852 SvREFCNT_dec (coro->on_destroy); 1853 SvREFCNT_dec (coro->on_destroy);
1853 SvREFCNT_dec (coro->status); 1854 SvREFCNT_dec (coro->status);
1854 1855
1855 Safefree (coro); 1856 Safefree (coro);
1856 1857
2504static void 2505static void
2505coro_rouse_callback (pTHX_ CV *cv) 2506coro_rouse_callback (pTHX_ CV *cv)
2506{ 2507{
2507 dXSARGS; 2508 dXSARGS;
2508 SV *data = (SV *)S_GENSUB_ARG; 2509 SV *data = (SV *)S_GENSUB_ARG;
2510 SV *coro = SvRV (data);
2509 2511
2510 /* data starts being the coro, and is replaced by the results when done */ 2512 /* data starts being either undef or a coro, and is replaced by the results when done */
2511 if (SvTYPE (SvRV (data)) != SVt_PVAV) 2513 if (SvTYPE (coro) != SVt_PVAV)
2512 { 2514 {
2513 /* first call, set args */ 2515 /* first call, set args */
2514 SV *coro = SvRV (data);
2515 AV *av = newAV ();
2516 2516
2517 SvRV_set (data, (SV *)av); 2517 assert (&ST (0) < &ST (1)); /* ensure the stack is in the order we expect it to be */
2518 SvRV_set (data, (SV *)av_make (items, &ST (0))); /* av_make copies the SVs */
2518 2519
2519 /* better take a full copy of the arguments */ 2520 if (coro != &PL_sv_undef)
2520 while (items--) 2521 {
2521 av_store (av, items, newSVsv (ST (items)));
2522
2523 api_ready (aTHX_ coro); 2522 api_ready (aTHX_ coro);
2524 SvREFCNT_dec_NN (coro); 2523 SvREFCNT_dec_NN (coro);
2524 }
2525 } 2525 }
2526 2526
2527 XSRETURN_EMPTY; 2527 XSRETURN_EMPTY;
2528} 2528}
2529 2529
2546 2546
2547 EXTEND (SP, AvFILLp (av) + 1); 2547 EXTEND (SP, AvFILLp (av) + 1);
2548 for (i = 0; i <= AvFILLp (av); ++i) 2548 for (i = 0; i <= AvFILLp (av); ++i)
2549 PUSHs (sv_2mortal (AvARRAY (av)[i])); 2549 PUSHs (sv_2mortal (AvARRAY (av)[i]));
2550 2550
2551 /* we have stolen the elements, so set length to zero and free */ 2551 /* we have stolen the elements, make it unreal and free */
2552 AvFILLp (av) = -1; 2552 AvREAL_off (av);
2553 av_undef (av); 2553 av_undef (av);
2554 2554
2555 PUTBACK; 2555 PUTBACK;
2556 } 2556 }
2557 2557
2582 croak ("Coro::rouse_wait called with illegal callback argument,"); 2582 croak ("Coro::rouse_wait called with illegal callback argument,");
2583 2583
2584 { 2584 {
2585 CV *cv = (CV *)SvRV (cb); /* for S_GENSUB_ARG */ 2585 CV *cv = (CV *)SvRV (cb); /* for S_GENSUB_ARG */
2586 SV *data = (SV *)S_GENSUB_ARG; 2586 SV *data = (SV *)S_GENSUB_ARG;
2587 int data_ready = SvTYPE (SvRV (data)) == SVt_PVAV;
2588
2589 /* if there is no data, we need to store the current coro in the reference so we can be woken up */
2590 if (!data_ready)
2591 if (SvRV (data) != &PL_sv_undef)
2592 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");
2593 else
2594 SvRV_set (data, SvREFCNT_inc_NN (SvRV (coro_current)));
2587 2595
2588 frame->data = (void *)data; 2596 frame->data = (void *)data;
2589 frame->prepare = SvTYPE (SvRV (data)) == SVt_PVAV ? prepare_nop : prepare_schedule; 2597 frame->prepare = data_ready ? prepare_nop : prepare_schedule;
2590 frame->check = slf_check_rouse_wait; 2598 frame->check = slf_check_rouse_wait;
2591 } 2599 }
2592} 2600}
2593 2601
2594static SV * 2602static SV *
2595coro_new_rouse_cb (pTHX) 2603coro_new_rouse_cb (pTHX)
2596{ 2604{
2597 HV *hv = (HV *)SvRV (coro_current); 2605 HV *hv = (HV *)SvRV (coro_current);
2598 struct coro *coro = SvSTATE_hv (hv); 2606 struct coro *coro = SvSTATE_hv (hv);
2599 SV *data = newRV_inc ((SV *)hv); 2607 SV *data = newRV_noinc (&PL_sv_undef);
2600 SV *cb = s_gensub (aTHX_ coro_rouse_callback, (void *)data); 2608 SV *cb = s_gensub (aTHX_ coro_rouse_callback, (void *)data);
2601 2609
2602 sv_magicext (SvRV (cb), data, CORO_MAGIC_type_rouse, 0, 0, 0); 2610 sv_magicext (SvRV (cb), data, CORO_MAGIC_type_rouse, 0, 0, 0);
2603 SvREFCNT_dec_NN (data); /* magicext increases the refcount */ 2611 SvREFCNT_dec_NN (data); /* magicext increases the refcount */
2604 2612

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines