summaryrefslogtreecommitdiff
path: root/perl.c
diff options
context:
space:
mode:
authorGurusamy Sarathy <gsar@cpan.org>2001-07-05 00:42:49 +0000
committerGurusamy Sarathy <gsar@cpan.org>2001-07-05 00:42:49 +0000
commit50dd6e574ff39b609595ddb16b2fe9f625a26f8c (patch)
tree75623d7252059f79bb9271a8ea59619aaee0be4f /perl.c
parentd3a7fa0a676f35fac595b7197c9c94e498857827 (diff)
downloadperl-50dd6e574ff39b609595ddb16b2fe9f625a26f8c.tar.gz
perl built with USE_ITHREADS can deadlock during fork() or backticks
since it doesn't ensure threads other than the one calling fork() aren't holding any locks; the fix is to use pthread_atfork() to hold global locks building perl with -Dusemymalloc exacerbates the problem since Perl_malloc() holds a mutex, and perl's exec() calls New() XXX the code in win32thread.h may be needed on platforms that have no pthread_atfork() p4raw-id: //depot/perl@11151
Diffstat (limited to 'perl.c')
-rw-r--r--perl.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/perl.c b/perl.c
index 935ab3d81a..cef5c4783a 100644
--- a/perl.c
+++ b/perl.c
@@ -58,6 +58,32 @@ static I32 read_e_script(pTHXo_ int idx, SV *buf_sv, int maxlen);
} STMT_END
#else
# if defined(USE_ITHREADS)
+
+static void S_atfork_lock(void);
+static void S_atfork_unlock(void);
+
+/* this is called in parent before the fork() */
+static void
+S_atfork_lock(void)
+{
+ /* locks must be held in locking order (if any) */
+#ifdef MYMALLOC
+ MUTEX_LOCK(&PL_malloc_mutex);
+#endif
+ OP_REFCNT_LOCK;
+}
+
+/* this is called in both parent and child after the fork() */
+static void
+S_atfork_unlock(void)
+{
+ /* locks must be released in same order as in S_atfork_lock() */
+#ifdef MYMALLOC
+ MUTEX_UNLOCK(&PL_malloc_mutex);
+#endif
+ OP_REFCNT_UNLOCK;
+}
+
# define INIT_TLS_AND_INTERP \
STMT_START { \
if (!PL_curinterp) { \
@@ -66,6 +92,9 @@ static I32 read_e_script(pTHXo_ int idx, SV *buf_sv, int maxlen);
ALLOC_THREAD_KEY; \
PERL_SET_THX(my_perl); \
OP_REFCNT_INIT; \
+ PTHREAD_ATFORK(S_atfork_lock, \
+ S_atfork_unlock, \
+ S_atfork_unlock); \
} \
else { \
PERL_SET_THX(my_perl); \