… | |
… | |
356 | |
356 | |
357 | require_pv ("Time/HiRes.pm"); |
357 | require_pv ("Time/HiRes.pm"); |
358 | |
358 | |
359 | svp = hv_fetch (PL_modglobal, "Time::NVtime", 12, 0); |
359 | svp = hv_fetch (PL_modglobal, "Time::NVtime", 12, 0); |
360 | |
360 | |
361 | if (!svp) croak ("Time::HiRes is required, but missing."); |
361 | if (!svp) croak ("Time::HiRes is required, but missing. Caught"); |
362 | if (!SvIOK (*svp)) croak ("Time::NVtime isn't a function pointer"); |
362 | if (!SvIOK (*svp)) croak ("Time::NVtime isn't a function pointer. Caught"); |
363 | |
363 | |
364 | nvtime = INT2PTR (double (*)(), SvIV (*svp)); |
364 | nvtime = INT2PTR (double (*)(), SvIV (*svp)); |
365 | |
365 | |
366 | svp = hv_fetch (PL_modglobal, "Time::U2time", 12, 0); |
366 | svp = hv_fetch (PL_modglobal, "Time::U2time", 12, 0); |
367 | u2time = INT2PTR (void (*)(pTHX_ UV ret[2]), SvIV (*svp)); |
367 | u2time = INT2PTR (void (*)(pTHX_ UV ret[2]), SvIV (*svp)); |
… | |
… | |
2038 | } |
2038 | } |
2039 | } |
2039 | } |
2040 | } |
2040 | } |
2041 | |
2041 | |
2042 | static void |
2042 | static void |
2043 | slf_init_terminate (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items) |
2043 | coro_set_status (HV *coro_hv, SV **arg, int items) |
2044 | { |
2044 | { |
2045 | int i; |
|
|
2046 | HV *hv = (HV *)SvRV (coro_current); |
|
|
2047 | AV *av = newAV (); |
2045 | AV *av = newAV (); |
2048 | |
2046 | |
2049 | /* items are actually not so common, so optimise for this case */ |
2047 | /* items are actually not so common, so optimise for this case */ |
2050 | if (items) |
2048 | if (items) |
2051 | { |
2049 | { |
|
|
2050 | int i; |
|
|
2051 | |
2052 | av_extend (av, items - 1); |
2052 | av_extend (av, items - 1); |
2053 | |
2053 | |
2054 | for (i = 0; i < items; ++i) |
2054 | for (i = 0; i < items; ++i) |
2055 | av_push (av, SvREFCNT_inc_NN (arg [i])); |
2055 | av_push (av, SvREFCNT_inc_NN (arg [i])); |
2056 | } |
2056 | } |
2057 | |
2057 | |
2058 | hv_store (hv, "_status", sizeof ("_status") - 1, newRV_noinc ((SV *)av), 0); |
2058 | hv_store (coro_hv, "_status", sizeof ("_status") - 1, newRV_noinc ((SV *)av), 0); |
|
|
2059 | } |
2059 | |
2060 | |
|
|
2061 | static void |
|
|
2062 | slf_init_terminate_cancel_common (pTHX_ struct CoroSLF *frame, HV *coro_hv) |
|
|
2063 | { |
2060 | av_push (av_destroy, (SV *)newRV_inc ((SV *)hv)); /* RVinc for perl */ |
2064 | av_push (av_destroy, (SV *)newRV_inc ((SV *)coro_hv)); /* RVinc for perl */ |
2061 | api_ready (aTHX_ sv_manager); |
2065 | api_ready (aTHX_ sv_manager); |
2062 | |
2066 | |
2063 | frame->prepare = prepare_schedule; |
2067 | frame->prepare = prepare_schedule; |
2064 | frame->check = slf_check_repeat; |
2068 | frame->check = slf_check_repeat; |
2065 | |
2069 | |
2066 | /* as a minor optimisation, we could unwind all stacks here */ |
2070 | /* as a minor optimisation, we could unwind all stacks here */ |
2067 | /* but that puts extra pressure on pp_slf, and is not worth much */ |
2071 | /* but that puts extra pressure on pp_slf, and is not worth much */ |
2068 | /*coro_unwind_stacks (aTHX);*/ |
2072 | /*coro_unwind_stacks (aTHX);*/ |
|
|
2073 | } |
|
|
2074 | |
|
|
2075 | static void |
|
|
2076 | slf_init_terminate (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items) |
|
|
2077 | { |
|
|
2078 | HV *coro_hv = (HV *)SvRV (coro_current); |
|
|
2079 | |
|
|
2080 | coro_set_status (coro_hv, arg, items); |
|
|
2081 | slf_init_terminate_cancel_common (frame, coro_hv); |
|
|
2082 | } |
|
|
2083 | |
|
|
2084 | static void |
|
|
2085 | slf_init_cancel (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items) |
|
|
2086 | { |
|
|
2087 | HV *coro_hv; |
|
|
2088 | struct coro *coro; |
|
|
2089 | |
|
|
2090 | if (items <= 0) |
|
|
2091 | croak ("Coro::cancel called without coro object,"); |
|
|
2092 | |
|
|
2093 | coro = SvSTATE (arg [0]); |
|
|
2094 | coro_hv = coro->hv; |
|
|
2095 | |
|
|
2096 | coro_set_status (coro_hv, arg + 1, items - 1); |
|
|
2097 | |
|
|
2098 | /* cancelling the current coro is allowed, and equals terminate */ |
|
|
2099 | if (coro_hv == (HV *)SvRV (coro_current)) |
|
|
2100 | slf_init_terminate_cancel_common (frame, coro_hv); |
|
|
2101 | else |
|
|
2102 | { |
|
|
2103 | /* otherwise we cancel ourselves */ |
|
|
2104 | coro_state_destroy (aTHX_ coro); |
|
|
2105 | coro_call_on_destroy (aTHX_ coro); |
|
|
2106 | |
|
|
2107 | frame->prepare = prepare_nop; |
|
|
2108 | frame->check = slf_check_nop; |
|
|
2109 | } |
2069 | } |
2110 | } |
2070 | |
2111 | |
2071 | /*****************************************************************************/ |
2112 | /*****************************************************************************/ |
2072 | /* async pool handler */ |
2113 | /* async pool handler */ |
2073 | |
2114 | |
… | |
… | |
3182 | transfer (...) |
3223 | transfer (...) |
3183 | PROTOTYPE: $$ |
3224 | PROTOTYPE: $$ |
3184 | CODE: |
3225 | CODE: |
3185 | CORO_EXECUTE_SLF_XS (slf_init_transfer); |
3226 | CORO_EXECUTE_SLF_XS (slf_init_transfer); |
3186 | |
3227 | |
3187 | bool |
|
|
3188 | _destroy (SV *coro_sv) |
|
|
3189 | CODE: |
|
|
3190 | RETVAL = coro_state_destroy (aTHX_ SvSTATE (coro_sv)); |
|
|
3191 | OUTPUT: |
|
|
3192 | RETVAL |
|
|
3193 | |
|
|
3194 | void |
3228 | void |
3195 | _exit (int code) |
3229 | _exit (int code) |
3196 | PROTOTYPE: $ |
3230 | PROTOTYPE: $ |
3197 | CODE: |
3231 | CODE: |
3198 | _exit (code); |
3232 | _exit (code); |
… | |
… | |
3393 | |
3427 | |
3394 | void |
3428 | void |
3395 | cancel (Coro::State self) |
3429 | cancel (Coro::State self) |
3396 | CODE: |
3430 | CODE: |
3397 | coro_state_destroy (aTHX_ self); |
3431 | coro_state_destroy (aTHX_ self); |
3398 | coro_call_on_destroy (aTHX_ self); /* actually only for Coro objects */ |
|
|
3399 | |
3432 | |
3400 | SV * |
3433 | SV * |
3401 | enable_times (int enabled = enable_times) |
3434 | enable_times (int enabled = enable_times) |
3402 | CODE: |
3435 | CODE: |
3403 | { |
3436 | { |
… | |
… | |
3508 | api_ready (aTHX_ RETVAL); |
3541 | api_ready (aTHX_ RETVAL); |
3509 | OUTPUT: |
3542 | OUTPUT: |
3510 | RETVAL |
3543 | RETVAL |
3511 | |
3544 | |
3512 | void |
3545 | void |
|
|
3546 | _destroy (Coro::State coro) |
|
|
3547 | CODE: |
|
|
3548 | /* used by the manager thread */ |
|
|
3549 | coro_state_destroy (aTHX_ coro); |
|
|
3550 | coro_call_on_destroy (aTHX_ coro); |
|
|
3551 | |
|
|
3552 | void |
3513 | terminate (...) |
3553 | terminate (...) |
3514 | CODE: |
3554 | CODE: |
3515 | CORO_EXECUTE_SLF_XS (slf_init_terminate); |
3555 | CORO_EXECUTE_SLF_XS (slf_init_terminate); |
|
|
3556 | |
|
|
3557 | void |
|
|
3558 | cancel (...) |
|
|
3559 | CODE: |
|
|
3560 | CORO_EXECUTE_SLF_XS (slf_init_cancel); |
3516 | |
3561 | |
3517 | void |
3562 | void |
3518 | schedule (...) |
3563 | schedule (...) |
3519 | CODE: |
3564 | CODE: |
3520 | CORO_EXECUTE_SLF_XS (slf_init_schedule); |
3565 | CORO_EXECUTE_SLF_XS (slf_init_schedule); |