]> git.vpit.fr Git - perl/modules/Variable-Magic.git/commitdiff
Free the thread local context from an atexit callback
authorVincent Pit <vince@profvince.com>
Mon, 30 Nov 2009 00:12:05 +0000 (01:12 +0100)
committerVincent Pit <vince@profvince.com>
Mon, 30 Nov 2009 00:12:25 +0000 (01:12 +0100)
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.

Magic.xs

index 003f52ef84d7df4c91f6a9d0a3cdcba776708cf5..a3f40c8a3015cc416450c43f623a33168d2cb419 100644 (file)
--- 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 */