]> git.vpit.fr Git - perl/modules/Variable-Magic.git/blobdiff - Magic.xs
Make the module threadsafe by adding a CLONE method that clones the global state...
[perl/modules/Variable-Magic.git] / Magic.xs
index 82bf5dd022c5a614e9f15095f7f72a1c7cdd0453..89df570ec4d896ae54599ad0408221dccbcb1a64 100644 (file)
--- a/Magic.xs
+++ b/Magic.xs
 #endif
 
 #ifndef dMY_CXT
-# define MY_CXT vmg_globaldata
 # define dMY_CXT
+# undef  MY_CXT
+# define MY_CXT vmg_globaldata
+# undef  START_MY_CXT
 # define START_MY_CXT STATIC my_cxt_t MY_CXT;
+# undef  MY_CXT_INIT
 # define MY_CXT_INIT
+# undef  MY_CXT_CLONE
+# undef  aMY_CXT
+# undef  pMY_CXT
+# define VMG_THREADSAFE 0
+#else
+# define VMG_THREADSAFE 1
 #endif
 
 #ifndef PERL_MAGIC_ext
@@ -129,6 +138,23 @@ typedef struct {
 
 START_MY_CXT
 
+STATIC void vmg_cxt_init
+#if defined(pMY_CXT) && defined(aMY_CXT)
+ (pTHX_ pMY_CXT) {
+# define vmg_cxt_init() vmg_cxt_init(aTHX_ aMY_CXT)
+#else
+ (pTHX) {
+ dMY_CXT;
+# define vmg_cxt_init() vmg_cxt_init(aTHX)
+#endif
+ MY_CXT.wizz = newHV();
+#ifdef USE_ITHREADS
+ HvSHAREKEYS_off(MY_CXT.wizz);
+#endif
+ MY_CXT.count = 0;
+ return;
+}
+
 /* --- Signatures ---------------------------------------------------------- */
 
 #define SIG_MIN ((U16) (1u << 8))
@@ -700,8 +726,7 @@ BOOT:
 {
  HV *stash;
  MY_CXT_INIT;
- MY_CXT.wizz = newHV();
- MY_CXT.count = 0;
+ vmg_cxt_init();
  stash = gv_stashpv(__PACKAGE__, 1);
  newCONSTSUB(stash, "SIG_MIN",   newSVuv(SIG_MIN));
  newCONSTSUB(stash, "SIG_MAX",   newSVuv(SIG_MAX));
@@ -717,8 +742,18 @@ BOOT:
  newCONSTSUB(stash, "VMG_COMPAT_SCALAR_LENGTH_NOLEN",
                     newSVuv(VMG_COMPAT_SCALAR_LENGTH_NOLEN));
  newCONSTSUB(stash, "VMG_PERL_PATCHLEVEL", newSVuv(VMG_PERL_PATCHLEVEL));
+ newCONSTSUB(stash, "VMG_THREADSAFE",      newSVuv(VMG_THREADSAFE));
 }
 
+void
+CLONE(...)
+PROTOTYPE: DISABLE
+CODE:
+#ifdef MY_CXT_CLONE
+ MY_CXT_CLONE;
+ vmg_cxt_init();
+#endif
+
 SV *_wizard(...)
 PROTOTYPE: DISABLE
 PREINIT:
@@ -802,7 +837,7 @@ CODE:
 
  hv_store(MY_CXT.wizz, buf, sprintf(buf, "%u", sig), sv, 0);
  ++MY_CXT.count;
+
  RETVAL = newRV_noinc(sv);
 OUTPUT:
  RETVAL