… | |
… | |
769 | #endif |
769 | #endif |
770 | |
770 | |
771 | /* |
771 | /* |
772 | * This overrides the default magic get method of %SIG elements. |
772 | * This overrides the default magic get method of %SIG elements. |
773 | * The original one doesn't provide for reading back of PL_diehook/PL_warnhook |
773 | * The original one doesn't provide for reading back of PL_diehook/PL_warnhook |
774 | * and instead of tryign to save and restore the hash elements, we just provide |
774 | * and instead of trying to save and restore the hash elements, we just provide |
775 | * readback here. |
775 | * readback here. |
776 | * We only do this when the hook is != 0, as they are often set to 0 temporarily, |
|
|
777 | * not expecting this to actually change the hook. This is a potential problem |
|
|
778 | * when a schedule happens then, but we ignore this. |
|
|
779 | */ |
776 | */ |
780 | static int |
777 | static int |
781 | coro_sigelem_get (pTHX_ SV *sv, MAGIC *mg) |
778 | coro_sigelem_get (pTHX_ SV *sv, MAGIC *mg) |
782 | { |
779 | { |
783 | const char *s = MgPV_nolen_const (mg); |
780 | const char *s = MgPV_nolen_const (mg); |
… | |
… | |
836 | if (strEQ (s, "__WARN__")) svp = &PL_warnhook; |
833 | if (strEQ (s, "__WARN__")) svp = &PL_warnhook; |
837 | |
834 | |
838 | if (svp) |
835 | if (svp) |
839 | { |
836 | { |
840 | SV *old = *svp; |
837 | SV *old = *svp; |
841 | *svp = newSVsv (sv); |
838 | *svp = SvOK (sv) ? newSVsv (sv) : 0; |
842 | SvREFCNT_dec (old); |
839 | SvREFCNT_dec (old); |
843 | return 0; |
840 | return 0; |
844 | } |
841 | } |
845 | } |
842 | } |
846 | |
843 | |
… | |
… | |
938 | /* copy throw, in case it was set before coro_setup */ |
935 | /* copy throw, in case it was set before coro_setup */ |
939 | CORO_THROW = coro->except; |
936 | CORO_THROW = coro->except; |
940 | } |
937 | } |
941 | |
938 | |
942 | static void |
939 | static void |
943 | coro_destruct (pTHX_ struct coro *coro) |
940 | coro_unwind_stacks (pTHX) |
944 | { |
941 | { |
945 | if (!IN_DESTRUCT) |
942 | if (!IN_DESTRUCT) |
946 | { |
943 | { |
947 | /* restore all saved variables and stuff */ |
944 | /* restore all saved variables and stuff */ |
948 | LEAVE_SCOPE (0); |
945 | LEAVE_SCOPE (0); |
… | |
… | |
956 | POPSTACK_TO (PL_mainstack); |
953 | POPSTACK_TO (PL_mainstack); |
957 | |
954 | |
958 | /* unwind main stack */ |
955 | /* unwind main stack */ |
959 | dounwind (-1); |
956 | dounwind (-1); |
960 | } |
957 | } |
|
|
958 | } |
|
|
959 | |
|
|
960 | static void |
|
|
961 | coro_destruct_perl (pTHX_ struct coro *coro) |
|
|
962 | { |
|
|
963 | coro_unwind_stacks (aTHX); |
961 | |
964 | |
962 | SvREFCNT_dec (GvSV (PL_defgv)); |
965 | SvREFCNT_dec (GvSV (PL_defgv)); |
963 | SvREFCNT_dec (GvAV (PL_defgv)); |
966 | SvREFCNT_dec (GvAV (PL_defgv)); |
964 | SvREFCNT_dec (GvSV (PL_errgv)); |
967 | SvREFCNT_dec (GvSV (PL_errgv)); |
965 | SvREFCNT_dec (PL_defoutgv); |
968 | SvREFCNT_dec (PL_defoutgv); |
… | |
… | |
1277 | cctx_destroy (coro_cctx *cctx) |
1280 | cctx_destroy (coro_cctx *cctx) |
1278 | { |
1281 | { |
1279 | if (!cctx) |
1282 | if (!cctx) |
1280 | return; |
1283 | return; |
1281 | |
1284 | |
1282 | assert (cctx != cctx_current);//D temporary |
1285 | assert (("FATAL: tried to destroy current cctx", cctx != cctx_current));//D temporary? |
1283 | |
1286 | |
1284 | --cctx_count; |
1287 | --cctx_count; |
1285 | coro_destroy (&cctx->cctx); |
1288 | coro_destroy (&cctx->cctx); |
1286 | |
1289 | |
1287 | /* coro_transfer creates new, empty cctx's */ |
1290 | /* coro_transfer creates new, empty cctx's */ |
… | |
… | |
1405 | coro_setup (aTHX_ next); |
1408 | coro_setup (aTHX_ next); |
1406 | } |
1409 | } |
1407 | else |
1410 | else |
1408 | load_perl (aTHX_ next); |
1411 | load_perl (aTHX_ next); |
1409 | |
1412 | |
1410 | assert (!prev->cctx);//D temporary |
|
|
1411 | |
|
|
1412 | /* possibly untie and reuse the cctx */ |
1413 | /* possibly untie and reuse the cctx */ |
1413 | if (expect_true ( |
1414 | if (expect_true ( |
1414 | cctx_current->idle_sp == STACKLEVEL |
1415 | cctx_current->idle_sp == STACKLEVEL |
1415 | && !(cctx_current->flags & CC_TRACE) |
1416 | && !(cctx_current->flags & CC_TRACE) |
1416 | && !force_cctx |
1417 | && !force_cctx |
… | |
… | |
1471 | --coro_nready; |
1472 | --coro_nready; |
1472 | } |
1473 | } |
1473 | else |
1474 | else |
1474 | coro->flags |= CF_READY; /* make sure it is NOT put into the readyqueue */ |
1475 | coro->flags |= CF_READY; /* make sure it is NOT put into the readyqueue */ |
1475 | |
1476 | |
1476 | if (coro->mainstack && coro->mainstack != main_mainstack) |
1477 | if (coro->mainstack |
|
|
1478 | && coro->mainstack != main_mainstack |
|
|
1479 | && coro->slot |
|
|
1480 | && !PL_dirty) |
1477 | { |
1481 | { |
1478 | struct coro temp; |
1482 | struct coro temp; |
1479 | |
1483 | |
1480 | assert (("FATAL: tried to destroy currently running coroutine (please report)", !(coro->flags & CF_RUNNING))); |
1484 | assert (("FATAL: tried to destroy currently running coroutine", coro->mainstack != PL_mainstack)); |
1481 | |
1485 | |
1482 | save_perl (aTHX_ &temp); |
1486 | save_perl (aTHX_ &temp); |
1483 | load_perl (aTHX_ coro); |
1487 | load_perl (aTHX_ coro); |
1484 | |
1488 | |
1485 | coro_destruct (aTHX_ coro); |
1489 | coro_destruct_perl (aTHX_ coro); |
1486 | |
1490 | |
1487 | load_perl (aTHX_ &temp); |
1491 | load_perl (aTHX_ &temp); |
1488 | |
1492 | |
1489 | coro->slot = 0; |
1493 | coro->slot = 0; |
1490 | } |
1494 | } |
… | |
… | |
1862 | av_push (av_destroy, (SV *)newRV_inc ((SV *)hv)); /* RVinc for perl */ |
1866 | av_push (av_destroy, (SV *)newRV_inc ((SV *)hv)); /* RVinc for perl */ |
1863 | api_ready (aTHX_ sv_manager); |
1867 | api_ready (aTHX_ sv_manager); |
1864 | |
1868 | |
1865 | frame->prepare = prepare_schedule; |
1869 | frame->prepare = prepare_schedule; |
1866 | frame->check = slf_check_repeat; |
1870 | frame->check = slf_check_repeat; |
|
|
1871 | |
|
|
1872 | /* as a minor optimisation, we could unwind all stacks here */ |
|
|
1873 | /* but that puts extra pressure on pp_slf, and is not worth much */ |
|
|
1874 | /*coro_unwind_stacks (aTHX);*/ |
1867 | } |
1875 | } |
1868 | |
1876 | |
1869 | /*****************************************************************************/ |
1877 | /*****************************************************************************/ |
1870 | /* async pool handler */ |
1878 | /* async pool handler */ |
1871 | |
1879 | |
… | |
… | |
3126 | { |
3134 | { |
3127 | int i; |
3135 | int i; |
3128 | |
3136 | |
3129 | sv_pool_rss = coro_get_sv (aTHX_ "Coro::POOL_RSS" , TRUE); |
3137 | sv_pool_rss = coro_get_sv (aTHX_ "Coro::POOL_RSS" , TRUE); |
3130 | sv_pool_size = coro_get_sv (aTHX_ "Coro::POOL_SIZE" , TRUE); |
3138 | sv_pool_size = coro_get_sv (aTHX_ "Coro::POOL_SIZE" , TRUE); |
3131 | cv_coro_run = get_cv ( "Coro::_terminate", GV_ADD); |
3139 | cv_coro_run = get_cv ( "Coro::_coro_run" , GV_ADD); |
3132 | cv_coro_terminate = get_cv ( "Coro::terminate" , GV_ADD); |
3140 | cv_coro_terminate = get_cv ( "Coro::terminate" , GV_ADD); |
3133 | coro_current = coro_get_sv (aTHX_ "Coro::current" , FALSE); SvREADONLY_on (coro_current); |
3141 | coro_current = coro_get_sv (aTHX_ "Coro::current" , FALSE); SvREADONLY_on (coro_current); |
3134 | av_async_pool = coro_get_av (aTHX_ "Coro::async_pool", TRUE); |
3142 | av_async_pool = coro_get_av (aTHX_ "Coro::async_pool", TRUE); |
3135 | av_destroy = coro_get_av (aTHX_ "Coro::destroy" , TRUE); |
3143 | av_destroy = coro_get_av (aTHX_ "Coro::destroy" , TRUE); |
3136 | sv_manager = coro_get_sv (aTHX_ "Coro::manager" , TRUE); |
3144 | sv_manager = coro_get_sv (aTHX_ "Coro::manager" , TRUE); |