#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)
#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
} */
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 */
del_he(entry);
--xhv->xhv_keys;
}
+ UNLOCK_STRTAB_MUTEX;
break;
}
*/
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 */
}
++HeVAL(entry); /* use value slot as REFCNT */
+ UNLOCK_STRTAB_MUTEX;
return HeKEY_hek(entry);
}
#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 */
#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
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);
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);
* 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
#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 */