… | |
… | |
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 | |
1845 | static int |
1845 | static int |
1846 | coro_state_free (pTHX_ SV *sv, MAGIC *mg) |
1846 | coro_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 | |
… | |
… | |
2504 | static void |
2505 | static void |
2505 | coro_rouse_callback (pTHX_ CV *cv) |
2506 | coro_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 | |
2594 | static SV * |
2602 | static SV * |
2595 | coro_new_rouse_cb (pTHX) |
2603 | coro_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 | |