summaryrefslogtreecommitdiff
path: root/util.c
diff options
context:
space:
mode:
authorGurusamy Sarathy <gsar@cpan.org>1998-11-29 12:40:28 +0000
committerGurusamy Sarathy <gsar@cpan.org>1998-11-29 12:40:28 +0000
commitb099ddc068b2498767e6f04ac167d9633b895ec4 (patch)
treec5565911f062bddb5d68139f8aed5d8489d2a488 /util.c
parentbfc605f9e1d41dd7493c0c0fcfd1304c238dbe4d (diff)
downloadperl-b099ddc068b2498767e6f04ac167d9633b895ec4.tar.gz
various fixes for race conditions under threads: mutex locks based
on PL_threadnum were seriously flawed, since it means more than one thread could enter the critical region; PL_na was global instead of thread-local; child thread could finish and free thr structures before Thread->new() got around to creating the Thread object; cv_clone() needed locking, as it mucks with PL_comppad and other global data; new_struct_thread() needed to lock template-thread's mutex while copying its data p4raw-id: //depot/perl@2385
Diffstat (limited to 'util.c')
-rw-r--r--util.c39
1 files changed, 22 insertions, 17 deletions
diff --git a/util.c b/util.c
index 10f1cc76b2..3be6a91243 100644
--- a/util.c
+++ b/util.c
@@ -2837,11 +2837,6 @@ new_struct_thread(struct perl_thread *t)
thr->flags = THRf_R_JOINABLE;
MUTEX_INIT(&thr->mutex);
- PL_curcop = t->Tcurcop; /* XXX As good a guess as any? */
- PL_defstash = t->Tdefstash; /* XXX maybe these should */
- PL_curstash = t->Tcurstash; /* always be set to main? */
-
-
/* top_env needs to be non-zero. It points to an area
in which longjmp() stuff is stored, as C callstack
info there at least is thread specific this has to
@@ -2858,6 +2853,25 @@ new_struct_thread(struct perl_thread *t)
PL_in_eval = FALSE;
PL_restartop = 0;
+ PL_statname = NEWSV(66,0);
+ PL_maxscream = -1;
+ PL_regcompp = FUNC_NAME_TO_PTR(pregcomp);
+ PL_regexecp = FUNC_NAME_TO_PTR(regexec_flags);
+ PL_regindent = 0;
+ PL_reginterp_cnt = 0;
+ PL_lastscream = Nullsv;
+ PL_screamfirst = 0;
+ PL_screamnext = 0;
+ PL_reg_start_tmp = 0;
+ PL_reg_start_tmpl = 0;
+
+ /* parent thread's data needs to be locked while we make copy */
+ MUTEX_LOCK(&t->mutex);
+
+ PL_curcop = t->Tcurcop; /* XXX As good a guess as any? */
+ PL_defstash = t->Tdefstash; /* XXX maybe these should */
+ PL_curstash = t->Tcurstash; /* always be set to main? */
+
PL_tainted = t->Ttainted;
PL_curpm = t->Tcurpm; /* XXX No PMOP ref count */
PL_nrs = newSVsv(t->Tnrs);
@@ -2871,18 +2885,6 @@ new_struct_thread(struct perl_thread *t)
PL_bodytarget = newSVsv(t->Tbodytarget);
PL_toptarget = newSVsv(t->Ttoptarget);
- PL_statname = NEWSV(66,0);
- PL_maxscream = -1;
- PL_regcompp = FUNC_NAME_TO_PTR(pregcomp);
- PL_regexecp = FUNC_NAME_TO_PTR(regexec_flags);
- PL_regindent = 0;
- PL_reginterp_cnt = 0;
- PL_lastscream = Nullsv;
- PL_screamfirst = 0;
- PL_screamnext = 0;
- PL_reg_start_tmp = 0;
- PL_reg_start_tmpl = 0;
-
/* Initialise all per-thread SVs that the template thread used */
svp = AvARRAY(t->threadsv);
for (i = 0; i <= AvFILLp(t->threadsv); i++, svp++) {
@@ -2905,6 +2907,9 @@ new_struct_thread(struct perl_thread *t)
thr->next->prev = thr;
MUTEX_UNLOCK(&PL_threads_mutex);
+ /* done copying parent's state */
+ MUTEX_UNLOCK(&t->mutex);
+
#ifdef HAVE_THREAD_INTERN
init_thread_intern(thr);
#endif /* HAVE_THREAD_INTERN */