add missing OP_REFCNT_LOCK/UNLOCKs and document it
Dave Mitchell [Fri, 8 Dec 2006 22:20:41 +0000 (22:20 +0000)]
p4raw-id: //depot/perl@29488

op.h
sv.c

diff --git a/op.h b/op.h
index 7001be1..e3596b5 100644 (file)
--- a/op.h
+++ b/op.h
@@ -520,6 +520,15 @@ struct loop {
 #define OA_SCALARREF 7
 #define OA_OPTIONAL 8
 
+/* Op_REFCNT is a reference count at the head of each op tree: needed
+ * since the tree is shared between threads, and between cloned closure
+ * copies in the same thread. OP_REFCNT_LOCK/UNLOCK is used when modifying
+ * this count.
+ * The same mutex is used to protect the refcounts of the reg_trie_data
+ * and reg_ac_data structures, which are shared between duplicated
+ * regexes.
+ */
+
 #ifdef USE_ITHREADS
 #  define OP_REFCNT_INIT               MUTEX_INIT(&PL_op_mutex)
 #  ifdef PERL_CORE
diff --git a/sv.c b/sv.c
index a675df2..2665b77 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -10421,7 +10421,9 @@ Perl_ss_dup(pTHX_ PerlInterpreter *proto_perl, CLONE_PARAMS* param)
                case OP_LEAVEWRITE:
                    TOPPTR(nss,ix) = ptr;
                    o = (OP*)ptr;
+                   OP_REFCNT_LOCK;
                    OpREFCNT_inc(o);
+                   OP_REFCNT_UNLOCK;
                    break;
                default:
                    TOPPTR(nss,ix) = NULL;
@@ -10993,7 +10995,9 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags,
 
     /* current interpreter roots */
     PL_main_cv         = cv_dup_inc(proto_perl->Imain_cv, param);
+    OP_REFCNT_LOCK;
     PL_main_root       = OpREFCNT_inc(proto_perl->Imain_root);
+    OP_REFCNT_UNLOCK;
     PL_main_start      = proto_perl->Imain_start;
     PL_eval_root       = proto_perl->Ieval_root;
     PL_eval_start      = proto_perl->Ieval_start;