]> git.vpit.fr Git - perl/modules/Lexical-Types.git/commitdiff
Store the overriden pp_padsv into thread-local storage
authorVincent Pit <vince@profvince.com>
Fri, 3 Jul 2009 17:57:17 +0000 (19:57 +0200)
committerVincent Pit <vince@profvince.com>
Fri, 3 Jul 2009 17:57:17 +0000 (19:57 +0200)
This should fix some threading-related issues where lexical types introduction weren't caught.

Types.xs

index 221319fa07e4971edb9657afcfc6322f8d0f7b2f..f22d034577974e4dbd7dea2575e87f15b006b80e 100644 (file)
--- a/Types.xs
+++ b/Types.xs
 # define MY_CXT_INIT  NOOP
 # undef  MY_CXT_CLONE
 # define MY_CXT_CLONE NOOP
+# undef  pMY_CXT
+# define pMY_CXT
+# undef  pMY_CXT_
+# define pMY_CXT_
+# undef  aMY_CXT
+# define aMY_CXT
+# undef  aMY_CXT_
+# define aMY_CXT_
 #endif
 
 /* --- Helpers ------------------------------------------------------------- */
@@ -103,17 +111,26 @@ typedef struct {
 #define ptable_hints_store(T, K, V) ptable_hints_store(aTHX_ (T), (K), (V))
 #define ptable_hints_free(T)        ptable_hints_free(aTHX_ (T))
 
+#endif /* LT_THREADSAFE || LT_WORKAROUND_REQUIRE_PROPAGATION */
+
+/* ... Global data ......................................................... */
+
 #define MY_CXT_KEY __PACKAGE__ "::_guts" XS_VERSION
 
 typedef struct {
+#if LT_THREADSAFE || LT_WORKAROUND_REQUIRE_PROPAGATION
  ptable *tbl; /* It really is a ptable_hints */
+#endif
 #if LT_THREADSAFE
  tTHX    owner;
 #endif
+ OP *  (*pp_padsv_saved)(pTHX);
 } my_cxt_t;
 
 START_MY_CXT
 
+/* ... Cloning global data ................................................. */
+
 #if LT_THREADSAFE
 
 STATIC void lt_ptable_hints_clone(pTHX_ ptable_ent *ent, void *ud_) {
@@ -160,6 +177,10 @@ STATIC void lt_thread_cleanup(pTHX_ void *ud) {
 
 #endif /* LT_THREADSAFE */
 
+/* ... Hint tags ........................................................... */
+
+#if LT_THREADSAFE || LT_WORKAROUND_REQUIRE_PROPAGATION
+
 STATIC SV *lt_tag(pTHX_ SV *value) {
 #define lt_tag(V) lt_tag(aTHX_ (V))
  lt_hint_t *h;
@@ -397,25 +418,27 @@ STATIC OP *lt_pp_padsv(pTHX) {
  return CALL_FPTR(PL_ppaddr[OP_PADSV])(aTHX);
 }
 
-STATIC OP *(*lt_pp_padsv_saved)(pTHX) = 0;
-
-STATIC void lt_pp_padsv_save(void) {
- if (lt_pp_padsv_saved)
+STATIC void lt_pp_padsv_save(pMY_CXT) {
+#define lt_pp_padsv_save() lt_pp_padsv_save(aMY_CXT)
+ if (MY_CXT.pp_padsv_saved)
   return;
 
lt_pp_padsv_saved   = PL_ppaddr[OP_PADSV];
- PL_ppaddr[OP_PADSV] = lt_pp_padsv;
MY_CXT.pp_padsv_saved = PL_ppaddr[OP_PADSV];
+ PL_ppaddr[OP_PADSV]   = lt_pp_padsv;
 }
 
-STATIC void lt_pp_padsv_restore(OP *o) {
- if (!lt_pp_padsv_saved)
+STATIC void lt_pp_padsv_restore(pMY_CXT_ OP *o) {
+#define lt_pp_padsv_restore(O) lt_pp_padsv_restore(aMY_CXT_ (O))
+ OP *(*saved)(pTHX) = MY_CXT.pp_padsv_saved;
+
+ if (!saved)
   return;
 
  if (o->op_ppaddr == lt_pp_padsv)
-  o->op_ppaddr = lt_pp_padsv_saved;
+  o->op_ppaddr = saved;
 
- PL_ppaddr[OP_PADSV] = lt_pp_padsv_saved;
lt_pp_padsv_saved   = 0;
+ PL_ppaddr[OP_PADSV]   = saved;
MY_CXT.pp_padsv_saved = 0;
 }
 
 /* ... Our ck_pad{any,sv} .................................................. */
@@ -435,6 +458,7 @@ STATIC OP *(*lt_old_ck_padany)(pTHX_ OP *) = 0;
 STATIC OP *lt_ck_padany(pTHX_ OP *o) {
  HV *stash;
  SV *code;
+ dMY_CXT;
 
  lt_pp_padsv_restore(o);
 
@@ -501,7 +525,7 @@ STATIC OP *lt_ck_padany(pTHX_ OP *o) {
 
   lt_pp_padsv_save();
 
-  lt_map_store(o, orig_pkg, type_pkg, type_meth, lt_pp_padsv_saved);
+  lt_map_store(o, orig_pkg, type_pkg, type_meth, MY_CXT.pp_padsv_saved);
  } else {
 skip:
   lt_map_delete(o);
@@ -513,6 +537,8 @@ skip:
 STATIC OP *(*lt_old_ck_padsv)(pTHX_ OP *) = 0;
 
 STATIC OP *lt_ck_padsv(pTHX_ OP *o) {
+ dMY_CXT;
+
  lt_pp_padsv_restore(o);
 
  lt_map_delete(o);
@@ -532,13 +558,15 @@ BOOT:
 {                                    
  if (!lt_initialized++) {
   HV *stash;
-#if LT_THREADSAFE || LT_WORKAROUND_REQUIRE_PROPAGATION
+
   MY_CXT_INIT;
-  MY_CXT.tbl   = ptable_new();
+#if LT_THREADSAFE || LT_WORKAROUND_REQUIRE_PROPAGATION
+  MY_CXT.tbl            = ptable_new();
 #endif
 #if LT_THREADSAFE
-  MY_CXT.owner = aTHX;
+  MY_CXT.owner          = aTHX;
 #endif
+  MY_CXT.pp_padsv_saved = 0;
 
   lt_op_map = ptable_new();
 #ifdef USE_ITHREADS
@@ -578,8 +606,9 @@ CODE:
  }
  {
   MY_CXT_CLONE;
-  MY_CXT.tbl   = t;
-  MY_CXT.owner = aTHX;
+  MY_CXT.tbl            = t;
+  MY_CXT.owner          = aTHX;
+  MY_CXT.pp_padsv_saved = 0;
  }
  {
   level = PerlMemShared_malloc(sizeof *level);