--- Coro/Coro/State.xs 2009/06/10 00:47:24 1.349 +++ Coro/Coro/State.xs 2009/06/20 08:58:00 1.350 @@ -992,25 +992,45 @@ static void coro_destruct_perl (pTHX_ struct coro *coro) { - coro_unwind_stacks (aTHX); + SV *svf [9]; - SvREFCNT_dec (GvSV (PL_defgv)); - SvREFCNT_dec (GvAV (PL_defgv)); - SvREFCNT_dec (GvSV (PL_errgv)); - SvREFCNT_dec (PL_defoutgv); - SvREFCNT_dec (PL_rs); - SvREFCNT_dec (GvSV (irsgv)); - SvREFCNT_dec (GvHV (PL_hintgv)); + { + struct coro *current = SvSTATE_current; - SvREFCNT_dec (PL_diehook); - SvREFCNT_dec (PL_warnhook); - - SvREFCNT_dec (coro->saved_deffh); - SvREFCNT_dec (coro->rouse_cb); - SvREFCNT_dec (coro->invoke_cb); - SvREFCNT_dec (coro->invoke_av); + assert (("FATAL: tried to destroy currently running coroutine", coro->mainstack != PL_mainstack)); + + save_perl (aTHX_ current); + load_perl (aTHX_ coro); + coro_unwind_stacks (aTHX); + coro_destruct_stacks (aTHX); + + // now save some sv's to be free'd later + svf [0] = GvSV (PL_defgv); + svf [1] = (SV *)GvAV (PL_defgv); + svf [2] = GvSV (PL_errgv); + svf [3] = (SV *)PL_defoutgv; + svf [4] = PL_rs; + svf [5] = GvSV (irsgv); + svf [6] = (SV *)GvHV (PL_hintgv); + svf [7] = PL_diehook; + svf [8] = PL_warnhook; + + assert (9 == sizeof (svf) / sizeof (*svf)); + + load_perl (aTHX_ current); + } + + { + int i; + + for (i = 0; i < sizeof (svf) / sizeof (*svf); ++i) + SvREFCNT_dec (svf [i]); - coro_destruct_stacks (aTHX); + SvREFCNT_dec (coro->saved_deffh); + SvREFCNT_dec (coro->rouse_cb); + SvREFCNT_dec (coro->invoke_cb); + SvREFCNT_dec (coro->invoke_av); + } } INLINE void @@ -1507,20 +1527,7 @@ && coro->mainstack != main_mainstack && coro->slot && !PL_dirty) - { - struct coro *current = SvSTATE_current; - - assert (("FATAL: tried to destroy currently running coroutine", coro->mainstack != PL_mainstack)); - - save_perl (aTHX_ current); - load_perl (aTHX_ coro); - - coro_destruct_perl (aTHX_ coro); - - load_perl (aTHX_ current); - - coro->slot = 0; - } + coro_destruct_perl (aTHX_ coro); cctx_destroy (coro->cctx); SvREFCNT_dec (coro->startcv);