… | |
… | |
2 | #define USE_NO_MINGW_SETJMP_TWO_ARGS |
2 | #define USE_NO_MINGW_SETJMP_TWO_ARGS |
3 | |
3 | |
4 | #define NDEBUG 1 /* perl usually disables NDEBUG later */ |
4 | #define NDEBUG 1 /* perl usually disables NDEBUG later */ |
5 | |
5 | |
6 | #include "libcoro/coro.c" |
6 | #include "libcoro/coro.c" |
|
|
7 | |
|
|
8 | #if CORO_UCONTEXT |
|
|
9 | #define CORO_BACKEND "ucontext" |
|
|
10 | #elif CORO_SJLJ |
|
|
11 | #define CORO_BACKEND "sjlj" |
|
|
12 | #elif CORO_LINUX |
|
|
13 | #define CORO_BACKEND "linux" |
|
|
14 | #elif CORO_LOSER |
|
|
15 | #define CORO_BACKEND "loser" |
|
|
16 | #elif CORO_FIBER |
|
|
17 | #define CORO_BACKEND "fiber" |
|
|
18 | #elif CORO_IRIX |
|
|
19 | #define CORO_BACKEND "irix" |
|
|
20 | #elif CORO_ASM |
|
|
21 | #define CORO_BACKEND "asm" |
|
|
22 | #elif CORO_PTHREAD |
|
|
23 | #define CORO_BACKEND "pthread" |
|
|
24 | #else |
|
|
25 | #define CORO_BACKEND "unknown" |
|
|
26 | #endif |
7 | |
27 | |
8 | #define PERL_NO_GET_CONTEXT |
28 | #define PERL_NO_GET_CONTEXT |
9 | #define PERL_EXT |
29 | #define PERL_EXT |
10 | |
30 | |
11 | #include "EXTERN.h" |
31 | #include "EXTERN.h" |
… | |
… | |
2461 | |
2481 | |
2462 | 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)) |
2463 | api_trace (aTHX_ coro_current, 0); |
2483 | api_trace (aTHX_ coro_current, 0); |
2464 | |
2484 | |
2465 | frame->prepare = prepare_schedule; |
2485 | frame->prepare = prepare_schedule; |
2466 | av_push (av_async_pool, SvREFCNT_inc (hv)); |
2486 | av_push (av_async_pool, SvREFCNT_inc_NN (hv)); |
2467 | } |
2487 | } |
2468 | } |
2488 | } |
2469 | else |
2489 | else |
2470 | { |
2490 | { |
2471 | /* first iteration, simply fall through */ |
2491 | /* first iteration, simply fall through */ |
… | |
… | |
2485 | coro_rouse_callback (pTHX_ CV *cv) |
2505 | coro_rouse_callback (pTHX_ CV *cv) |
2486 | { |
2506 | { |
2487 | dXSARGS; |
2507 | dXSARGS; |
2488 | SV *data = (SV *)S_GENSUB_ARG; |
2508 | SV *data = (SV *)S_GENSUB_ARG; |
2489 | |
2509 | |
|
|
2510 | /* data starts being the coro, and is replaced by the results when done */ |
2490 | if (SvTYPE (SvRV (data)) != SVt_PVAV) |
2511 | if (SvTYPE (SvRV (data)) != SVt_PVAV) |
2491 | { |
2512 | { |
2492 | /* first call, set args */ |
2513 | /* first call, set args */ |
2493 | SV *coro = SvRV (data); |
2514 | SV *coro = SvRV (data); |
2494 | AV *av = newAV (); |
2515 | AV *av = newAV (); |
… | |
… | |
2498 | /* better take a full copy of the arguments */ |
2519 | /* better take a full copy of the arguments */ |
2499 | while (items--) |
2520 | while (items--) |
2500 | av_store (av, items, newSVsv (ST (items))); |
2521 | av_store (av, items, newSVsv (ST (items))); |
2501 | |
2522 | |
2502 | api_ready (aTHX_ coro); |
2523 | api_ready (aTHX_ coro); |
2503 | SvREFCNT_dec (coro); |
2524 | SvREFCNT_dec_NN (coro); |
2504 | } |
2525 | } |
2505 | |
2526 | |
2506 | XSRETURN_EMPTY; |
2527 | XSRETURN_EMPTY; |
2507 | } |
2528 | } |
2508 | |
2529 | |
… | |
… | |
2577 | struct coro *coro = SvSTATE_hv (hv); |
2598 | struct coro *coro = SvSTATE_hv (hv); |
2578 | SV *data = newRV_inc ((SV *)hv); |
2599 | SV *data = newRV_inc ((SV *)hv); |
2579 | SV *cb = s_gensub (aTHX_ coro_rouse_callback, (void *)data); |
2600 | SV *cb = s_gensub (aTHX_ coro_rouse_callback, (void *)data); |
2580 | |
2601 | |
2581 | sv_magicext (SvRV (cb), data, CORO_MAGIC_type_rouse, 0, 0, 0); |
2602 | sv_magicext (SvRV (cb), data, CORO_MAGIC_type_rouse, 0, 0, 0); |
2582 | SvREFCNT_dec (data); /* magicext increases the refcount */ |
2603 | SvREFCNT_dec_NN (data); /* magicext increases the refcount */ |
2583 | |
2604 | |
2584 | SvREFCNT_dec (coro->rouse_cb); |
2605 | SvREFCNT_dec (coro->rouse_cb); |
2585 | coro->rouse_cb = SvREFCNT_inc_NN (cb); |
2606 | coro->rouse_cb = SvREFCNT_inc_NN (cb); |
2586 | |
2607 | |
2587 | return cb; |
2608 | return cb; |
… | |
… | |
3674 | rv_diehook = newRV_inc ((SV *)gv_fetchpv ("Coro::State::diehook" , 0, SVt_PVCV)); |
3695 | rv_diehook = newRV_inc ((SV *)gv_fetchpv ("Coro::State::diehook" , 0, SVt_PVCV)); |
3675 | rv_warnhook = newRV_inc ((SV *)gv_fetchpv ("Coro::State::warnhook", 0, SVt_PVCV)); |
3696 | rv_warnhook = newRV_inc ((SV *)gv_fetchpv ("Coro::State::warnhook", 0, SVt_PVCV)); |
3676 | |
3697 | |
3677 | coro_state_stash = gv_stashpv ("Coro::State", TRUE); |
3698 | coro_state_stash = gv_stashpv ("Coro::State", TRUE); |
3678 | |
3699 | |
|
|
3700 | newCONSTSUB (coro_state_stash, "BACKEND", newSVpv (CORO_BACKEND, 0)); /* undocumented */ |
|
|
3701 | |
3679 | newCONSTSUB (coro_state_stash, "CC_TRACE" , newSViv (CC_TRACE)); |
3702 | newCONSTSUB (coro_state_stash, "CC_TRACE" , newSViv (CC_TRACE)); |
3680 | newCONSTSUB (coro_state_stash, "CC_TRACE_SUB" , newSViv (CC_TRACE_SUB)); |
3703 | newCONSTSUB (coro_state_stash, "CC_TRACE_SUB" , newSViv (CC_TRACE_SUB)); |
3681 | newCONSTSUB (coro_state_stash, "CC_TRACE_LINE", newSViv (CC_TRACE_LINE)); |
3704 | newCONSTSUB (coro_state_stash, "CC_TRACE_LINE", newSViv (CC_TRACE_LINE)); |
3682 | newCONSTSUB (coro_state_stash, "CC_TRACE_ALL" , newSViv (CC_TRACE_ALL)); |
3705 | newCONSTSUB (coro_state_stash, "CC_TRACE_ALL" , newSViv (CC_TRACE_ALL)); |
3683 | |
3706 | |
… | |
… | |
3807 | call (Coro::State coro, SV *coderef) |
3830 | call (Coro::State coro, SV *coderef) |
3808 | ALIAS: |
3831 | ALIAS: |
3809 | eval = 1 |
3832 | eval = 1 |
3810 | CODE: |
3833 | CODE: |
3811 | { |
3834 | { |
|
|
3835 | struct coro *current = SvSTATE_current; |
|
|
3836 | |
3812 | if (coro->mainstack && ((coro->flags & CF_RUNNING) || coro->slot)) |
3837 | if ((coro == current) || (coro->mainstack && ((coro->flags & CF_RUNNING) || coro->slot))) |
3813 | { |
3838 | { |
3814 | struct coro *current = SvSTATE_current; |
|
|
3815 | struct CoroSLF slf_save; |
3839 | struct CoroSLF slf_save; |
3816 | |
3840 | |
3817 | if (current != coro) |
3841 | if (current != coro) |
3818 | { |
3842 | { |
3819 | PUTBACK; |
3843 | PUTBACK; |