summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGurusamy Sarathy <gsar@cpan.org>1998-09-24 03:36:30 +0000
committerGurusamy Sarathy <gsar@cpan.org>1998-09-24 03:36:30 +0000
commit5f08fbcd6341ee0f8f3c7dfe721098c3bfae1c67 (patch)
treea70127e53b67320af4d734e666f8494d502244f6
parent34b5802582e6ac0ab95ef6940fa408896842b141 (diff)
downloadperl-5f08fbcd6341ee0f8f3c7dfe721098c3bfae1c67.tar.gz
provide locked access to string table for USE_THREADS
p4raw-id: //depot/perl@1863
-rw-r--r--embedvar.h2
-rw-r--r--hv.c4
-rw-r--r--intrpvar.h1
-rw-r--r--objXSUB.h2
-rw-r--r--perl.c4
-rw-r--r--thread.h27
6 files changed, 34 insertions, 6 deletions
diff --git a/embedvar.h b/embedvar.h
index 8c1b786b97..be36de0430 100644
--- a/embedvar.h
+++ b/embedvar.h
@@ -252,6 +252,7 @@
#define PL_stdingv (PL_curinterp->Istdingv)
#define PL_strchop (PL_curinterp->Istrchop)
#define PL_strtab (PL_curinterp->Istrtab)
+#define PL_strtab_mutex (PL_curinterp->Istrtab_mutex)
#define PL_sub_generation (PL_curinterp->Isub_generation)
#define PL_sublex_info (PL_curinterp->Isublex_info)
#define PL_sv_arenaroot (PL_curinterp->Isv_arenaroot)
@@ -386,6 +387,7 @@
#define PL_Istdingv PL_stdingv
#define PL_Istrchop PL_strchop
#define PL_Istrtab PL_strtab
+#define PL_Istrtab_mutex PL_strtab_mutex
#define PL_Isub_generation PL_sub_generation
#define PL_Isublex_info PL_sublex_info
#define PL_Isv_arenaroot PL_sv_arenaroot
diff --git a/hv.c b/hv.c
index 40bb9b8e73..2416831256 100644
--- a/hv.c
+++ b/hv.c
@@ -1149,6 +1149,7 @@ unsharepvn(char *str, I32 len, U32 hash)
} */
xhv = (XPVHV*)SvANY(PL_strtab);
/* assert(xhv_array != 0) */
+ LOCK_STRTAB_MUTEX;
oentry = &((HE**)xhv->xhv_array)[hash & (I32) xhv->xhv_max];
for (entry = *oentry; entry; i=0, oentry = &HeNEXT(entry), entry = *oentry) {
if (HeHASH(entry) != hash) /* strings can't be equal */
@@ -1166,6 +1167,7 @@ unsharepvn(char *str, I32 len, U32 hash)
del_he(entry);
--xhv->xhv_keys;
}
+ UNLOCK_STRTAB_MUTEX;
break;
}
@@ -1193,6 +1195,7 @@ share_hek(char *str, I32 len, register U32 hash)
*/
xhv = (XPVHV*)SvANY(PL_strtab);
/* assert(xhv_array != 0) */
+ LOCK_STRTAB_MUTEX;
oentry = &((HE**)xhv->xhv_array)[hash & (I32) xhv->xhv_max];
for (entry = *oentry; entry; i=0, entry = HeNEXT(entry)) {
if (HeHASH(entry) != hash) /* strings can't be equal */
@@ -1219,6 +1222,7 @@ share_hek(char *str, I32 len, register U32 hash)
}
++HeVAL(entry); /* use value slot as REFCNT */
+ UNLOCK_STRTAB_MUTEX;
return HeKEY_hek(entry);
}
diff --git a/intrpvar.h b/intrpvar.h
index dfdcca8e1c..1f6244d557 100644
--- a/intrpvar.h
+++ b/intrpvar.h
@@ -199,6 +199,7 @@ PERLVAR(Isublex_info, SUBLEXINFO) /* from toke.c */
#ifdef USE_THREADS
PERLVAR(Ithrsv, SV *) /* struct perl_thread for main thread */
PERLVARI(Ithreadnum, U32, 0) /* incremented each thread creation */
+PERLVAR(Istrtab_mutex, perl_mutex) /* Mutex for string table access */
#endif /* USE_THREADS */
PERLVARI(Ibytecode_iv_overflows,int, 0) /* from bytecode.h */
diff --git a/objXSUB.h b/objXSUB.h
index 2c43839370..116075b93b 100644
--- a/objXSUB.h
+++ b/objXSUB.h
@@ -447,6 +447,8 @@
#define PL_strchop pPerl->PL_strchop
#undef PL_strtab
#define PL_strtab pPerl->PL_strtab
+#undef PL_strtab_mutex
+#define PL_strtab_mutex pPerl->PL_strtab_mutex
#undef PL_sub_generation
#define PL_sub_generation pPerl->PL_sub_generation
#undef PL_sublex_info
diff --git a/perl.c b/perl.c
index 79fab4a4ef..a5bb53649a 100644
--- a/perl.c
+++ b/perl.c
@@ -553,6 +553,7 @@ perl_destruct(register PerlInterpreter *sv_interp)
DEBUG_P(debprofdump());
#ifdef USE_THREADS
+ MUTEX_DESTROY(&PL_strtab_mutex);
MUTEX_DESTROY(&PL_sv_mutex);
MUTEX_DESTROY(&PL_eval_mutex);
COND_DESTROY(&PL_eval_cond);
@@ -1905,6 +1906,9 @@ init_main_stash(void)
about not iterating on it, and not adding tie magic to it.
It is properly deallocated in perl_destruct() */
PL_strtab = newHV();
+#ifdef USE_THREADS
+ MUTEX_INIT(&PL_strtab_mutex);
+#endif
HvSHAREKEYS_off(PL_strtab); /* mandatory */
hv_ksplit(PL_strtab, 512);
diff --git a/thread.h b/thread.h
index 3eb061a22a..035c5caec9 100644
--- a/thread.h
+++ b/thread.h
@@ -161,16 +161,29 @@ struct perl_thread *getTHR _((void));
* Systems with very fast mutexes (and/or slow conditionals) may wish to
* remove the "if (threadnum) ..." test.
*/
-#define LOCK_SV_MUTEX \
- STMT_START { \
+#define LOCK_SV_MUTEX \
+ STMT_START { \
+ if (PL_threadnum) \
+ MUTEX_LOCK(&PL_sv_mutex); \
+ } STMT_END
+
+#define UNLOCK_SV_MUTEX \
+ STMT_START { \
if (PL_threadnum) \
- MUTEX_LOCK(&PL_sv_mutex); \
+ MUTEX_UNLOCK(&PL_sv_mutex); \
} STMT_END
-#define UNLOCK_SV_MUTEX \
- STMT_START { \
+/* Likewise for strtab_mutex */
+#define LOCK_STRTAB_MUTEX \
+ STMT_START { \
+ if (PL_threadnum) \
+ MUTEX_LOCK(&PL_strtab_mutex); \
+ } STMT_END
+
+#define UNLOCK_STRTAB_MUTEX \
+ STMT_START { \
if (PL_threadnum) \
- MUTEX_UNLOCK(&PL_sv_mutex); \
+ MUTEX_UNLOCK(&PL_strtab_mutex); \
} STMT_END
#ifndef THREAD_RET_TYPE
@@ -223,6 +236,8 @@ typedef struct condpair {
#define COND_DESTROY(c)
#define LOCK_SV_MUTEX
#define UNLOCK_SV_MUTEX
+#define LOCK_STRTAB_MUTEX
+#define UNLOCK_STRTAB_MUTEX
#define THR
/* Rats: if dTHR is just blank then the subsequent ";" throws an error */