]> git.vpit.fr Git - perl/modules/Variable-Magic.git/blobdiff - Magic.xs
Free the thread local context from an atexit callback
[perl/modules/Variable-Magic.git] / Magic.xs
index 5a46c641761e3b63afc1c369b3b91ade09b0502e..a3f40c8a3015cc416450c43f623a33168d2cb419 100644 (file)
--- a/Magic.xs
+++ b/Magic.xs
@@ -363,26 +363,26 @@ STATIC void vmg_mgwiz_free(pTHX_ MGWIZ *w) {
  if (!w)
   return;
 
- if (w->cb_data)   SvREFCNT_dec(SvRV(w->cb_data));
- if (w->cb_get)    SvREFCNT_dec(SvRV(w->cb_get));
- if (w->cb_set)    SvREFCNT_dec(SvRV(w->cb_set));
- if (w->cb_len)    SvREFCNT_dec(SvRV(w->cb_len));
- if (w->cb_clear)  SvREFCNT_dec(SvRV(w->cb_clear));
- if (w->cb_free)   SvREFCNT_dec(SvRV(w->cb_free));
+ if (w->cb_data)   SvREFCNT_dec(w->cb_data);
+ if (w->cb_get)    SvREFCNT_dec(w->cb_get);
+ if (w->cb_set)    SvREFCNT_dec(w->cb_set);
+ if (w->cb_len)    SvREFCNT_dec(w->cb_len);
+ if (w->cb_clear)  SvREFCNT_dec(w->cb_clear);
+ if (w->cb_free)   SvREFCNT_dec(w->cb_free);
 #if MGf_COPY
- if (w->cb_copy)   SvREFCNT_dec(SvRV(w->cb_copy));
+ if (w->cb_copy)   SvREFCNT_dec(w->cb_copy);
 #endif /* MGf_COPY */
 #if 0 /* MGf_DUP */
- if (w->cb_dup)    SvREFCNT_dec(SvRV(w->cb_dup));
+ if (w->cb_dup)    SvREFCNT_dec(w->cb_dup);
 #endif /* MGf_DUP */
 #if MGf_LOCAL
- if (w->cb_local)  SvREFCNT_dec(SvRV(w->cb_local));
+ if (w->cb_local)  SvREFCNT_dec(w->cb_local);
 #endif /* MGf_LOCAL */
 #if VMG_UVAR
- if (w->cb_fetch)  SvREFCNT_dec(SvRV(w->cb_fetch));
- if (w->cb_store)  SvREFCNT_dec(SvRV(w->cb_store));
- if (w->cb_exists) SvREFCNT_dec(SvRV(w->cb_exists));
- if (w->cb_delete) SvREFCNT_dec(SvRV(w->cb_delete));
+ if (w->cb_fetch)  SvREFCNT_dec(w->cb_fetch);
+ if (w->cb_store)  SvREFCNT_dec(w->cb_store);
+ if (w->cb_exists) SvREFCNT_dec(w->cb_exists);
+ if (w->cb_delete) SvREFCNT_dec(w->cb_delete);
 #endif /* VMG_UVAR */
 
  Safefree(w->vtbl);
@@ -517,7 +517,7 @@ STATIC MGVTBL vmg_wizard_vtbl = {
 
 STATIC SV *vmg_wizard_new(pTHX_ const MGWIZ *w) {
 #define vmg_wizard_new(W) vmg_wizard_new(aTHX_ (W))
- SV *wiz = newSVuv(PTR2UV(w));
+ SV *wiz = newSVuv(PTR2IV(w));
 
  if (w) {
   MAGIC *mg = sv_magicext(wiz, NULL, PERL_MAGIC_ext, &vmg_wizard_vtbl, NULL, 0);
@@ -528,7 +528,7 @@ STATIC SV *vmg_wizard_new(pTHX_ const MGWIZ *w) {
  return wiz;
 }
 
-STATIC SV *vmg_wizard_validate(pTHX_ SV *wiz) {
+STATIC const SV *vmg_wizard_validate(pTHX_ const SV *wiz) {
 #define vmg_wizard_validate(W) vmg_wizard_validate(aTHX_ (W))
  if (SvROK(wiz)) {
   wiz = SvRV(wiz);
@@ -539,7 +539,7 @@ STATIC SV *vmg_wizard_validate(pTHX_ SV *wiz) {
  croak(vmg_invalid_wiz);
 }
 
-#define vmg_wizard_id(W)         SvUV((SV *) (W))
+#define vmg_wizard_id(W)         SvIVX((const SV *) (W))
 #define vmg_wizard_main_mgwiz(W) INT2PTR(const MGWIZ *, vmg_wizard_id(W))
 
 /* ... Wizard destructor ................................................... */
@@ -566,8 +566,8 @@ STATIC int vmg_wizard_free(pTHX_ SV *sv, MAGIC *mg) {
 
 #if VMG_THREADSAFE
 
-STATIC const MGWIZ *vmg_wizard_mgwiz(pTHX_ SV *wiz) {
-#define vmg_wizard_mgwiz(W) vmg_wizard_mgwiz(aTHX_ ((SV *) (W)))
+STATIC const MGWIZ *vmg_wizard_mgwiz(pTHX_ const SV *wiz) {
+#define vmg_wizard_mgwiz(W) vmg_wizard_mgwiz(aTHX_ ((const SV *) (W)))
  const MGWIZ *w;
 
  w = vmg_wizard_main_mgwiz(wiz);
@@ -588,8 +588,7 @@ STATIC const MGWIZ *vmg_wizard_mgwiz(pTHX_ SV *wiz) {
 
 /* --- User-level functions implementation --------------------------------- */
 
-STATIC const MAGIC *vmg_find(pTHX_ const SV *sv, SV *wiz) {
-#define vmg_find(S, W) vmg_find(aTHX_ (S), (W))
+STATIC const MAGIC *vmg_find(const SV *sv, const SV *wiz) {
  const MAGIC *mg, *moremagic;
  UV wid;
 
@@ -645,7 +644,7 @@ STATIC SV *vmg_data_new(pTHX_ SV *ctor, SV *sv, AV *args) {
  return nsv;
 }
 
-STATIC SV *vmg_data_get(pTHX_ SV *sv, SV *wiz) {
+STATIC SV *vmg_data_get(pTHX_ SV *sv, const SV *wiz) {
 #define vmg_data_get(S, W) vmg_data_get(aTHX_ (S), (W))
  const MAGIC *mg = vmg_find(sv, wiz);
  return mg ? mg->mg_obj : NULL;
@@ -668,7 +667,7 @@ STATIC void vmg_uvar_del(SV *sv, MAGIC *prevmagic, MAGIC *mg, MAGIC *moremagic)
 }
 #endif /* VMG_UVAR */
 
-STATIC UV vmg_cast(pTHX_ SV *sv, SV *wiz, AV *args) {
+STATIC UV vmg_cast(pTHX_ SV *sv, const SV *wiz, AV *args) {
 #define vmg_cast(S, W, A) vmg_cast(aTHX_ (S), (W), (A))
  MAGIC       *mg, *moremagic = NULL;
  SV          *data;
@@ -750,7 +749,7 @@ done:
  return 1;
 }
 
-STATIC UV vmg_dispell(pTHX_ SV *sv, SV *wiz) {
+STATIC UV vmg_dispell(pTHX_ SV *sv, const SV *wiz) {
 #define vmg_dispell(S, W) vmg_dispell(aTHX_ (S), (W))
 #if VMG_UVAR
  U32 uvars = 0;
@@ -990,7 +989,7 @@ STATIC U32 vmg_svt_len(pTHX_ SV *sv, MAGIC *mg) {
  PUSHs(mg->mg_obj ? mg->mg_obj : &PL_sv_undef);
  if (t < SVt_PVAV) {
   STRLEN l;
-  U8 *s = (U8 *) SvPV_const(sv, l);
+  const U8 *s = (const U8 *) SvPV_const(sv, l);
   if (DO_UTF8(sv))
    len = utf8_length(s, s + l);
   else
@@ -1245,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
@@ -1263,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);
@@ -1294,7 +1305,6 @@ CLONE(...)
 PROTOTYPE: DISABLE
 PREINIT:
  ptable *t;
- int    *level;
  U32     had_b__op_stash = 0;
  opclass c;
 PPCODE:
@@ -1403,7 +1413,6 @@ PREINIT:
  AV *args = NULL;
  SV *ret;
 CODE:
- wiz = vmg_wizard_validate(wiz);
  if (items > 2) {
   I32 i;
   args = newAV();
@@ -1414,7 +1423,7 @@ CODE:
    if (av_store(args, i - 2, arg) == NULL) croak(vmg_argstorefailed);
   }
  }
- ret = newSVuv(vmg_cast(SvRV(sv), wiz, args));
+ ret = newSVuv(vmg_cast(SvRV(sv), vmg_wizard_validate(wiz), args));
  SvREFCNT_dec(args);
  RETVAL = ret;
 OUTPUT:
@@ -1426,8 +1435,7 @@ PROTOTYPE: \[$@%&*]$
 PREINIT:
  SV *data;
 PPCODE:
- wiz  = vmg_wizard_validate(wiz);
- data = vmg_data_get(SvRV(sv), wiz);
+ data = vmg_data_get(SvRV(sv), vmg_wizard_validate(wiz));
  if (!data)
   XSRETURN_EMPTY;
  ST(0) = data;
@@ -1436,7 +1444,6 @@ PPCODE:
 SV *dispell(SV *sv, SV *wiz)
 PROTOTYPE: \[$@%&*]$
 CODE:
- wiz = vmg_wizard_validate(wiz);
- RETVAL = newSVuv(vmg_dispell(SvRV(sv), wiz));
+ RETVAL = newSVuv(vmg_dispell(SvRV(sv), vmg_wizard_validate(wiz)));
 OUTPUT:
  RETVAL