From: Vincent Pit Date: Mon, 30 Nov 2009 00:12:05 +0000 (+0100) Subject: Free the thread local context from an atexit callback X-Git-Tag: v0.39~10 X-Git-Url: http://git.vpit.fr/?p=perl%2Fmodules%2FVariable-Magic.git;a=commitdiff_plain;h=5cac4f283a7a2f4421a7f6f06d9d60cb9dfed630 Free the thread local context from an atexit callback They happen very late in the destruction process but that's not an issue there. The MGWIZ structure and the SVs they contain are destroyed and removed from the global pointer table when the wizard object is destroyed. At the time the atexit callback fires, the pointer table is then empty and the only thing left to do is to free its own (shared) memory. --- diff --git a/Magic.xs b/Magic.xs index 003f52e..a3f40c8 100644 --- a/Magic.xs +++ b/Magic.xs @@ -490,22 +490,6 @@ STATIC void vmg_ptable_clone(pTHX_ ptable_ent *ent, void *ud_) { ptable_store(ud->wizards, ent->key, w); } -STATIC void vmg_thread_cleanup(pTHX_ void *); - -STATIC void vmg_thread_cleanup(pTHX_ void *ud) { - int *level = ud; - - if (*level) { - --*level; - LEAVE; - SAVEDESTRUCTOR_X(vmg_thread_cleanup, level); - ENTER; - } else { - dMY_CXT; - PerlMemShared_free(level); - ptable_free(MY_CXT.wizards); - } -} #endif /* VMG_THREADSAFE */ /* --- Wizard objects ------------------------------------------------------ */ @@ -1260,6 +1244,17 @@ STATIC I32 vmg_svt_val(pTHX_ IV action, SV *sv) { w->cb_ ## N = NULL; \ } +#if VMG_THREADSAFE + +STATIC void vmg_cleanup(pTHX_ void *ud) { + dMY_CXT; + + ptable_free(MY_CXT.wizards); + MY_CXT.wizards = NULL; +} + +#endif /* VMG_THREADSAFE */ + /* --- XS ------------------------------------------------------------------ */ MODULE = Variable::Magic PACKAGE = Variable::Magic @@ -1278,6 +1273,7 @@ BOOT: MY_CXT.b__op_stashes[0] = NULL; #if VMG_THREADSAFE MUTEX_INIT(&vmg_op_name_init_mutex); + call_atexit(vmg_cleanup, NULL); #endif stash = gv_stashpv(__PACKAGE__, 1); @@ -1334,14 +1330,6 @@ PPCODE: ? gv_stashpv(vmg_opclassnames[c], 1) : NULL; } } - { - int *level; - level = PerlMemShared_malloc(sizeof *level); - *level = 1; - LEAVE; - SAVEDESTRUCTOR_X(vmg_thread_cleanup, level); - ENTER; - } XSRETURN(0); #endif /* VMG_THREADSAFE */