diff options
author | Gurusamy Sarathy <gsar@cpan.org> | 2001-07-05 00:42:49 +0000 |
---|---|---|
committer | Gurusamy Sarathy <gsar@cpan.org> | 2001-07-05 00:42:49 +0000 |
commit | 7d8f4fe511c0e703b183bbd6e19c8b6ca13f3dc9 (patch) | |
tree | 75623d7252059f79bb9271a8ea59619aaee0be4f /perl.c | |
parent | 3807896f8955d7e06d3507258eae5341191ffa1a (diff) | |
download | perl-7d8f4fe511c0e703b183bbd6e19c8b6ca13f3dc9.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.c | 29 |
1 files changed, 29 insertions, 0 deletions
@@ -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); \ |