diff options
-rw-r--r-- | perl.c | 29 | ||||
-rw-r--r-- | thread.h | 9 | ||||
-rw-r--r-- | win32/win32thread.h | 2 |
3 files changed, 40 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); \ @@ -302,6 +302,11 @@ } STMT_END #endif +#ifndef PTHREAD_ATFORK +# define PTHREAD_ATFORK(prepare,parent,child) \ + pthread_atfork(prepare,parent,child) +#endif + #ifndef THREAD_RET_TYPE # define THREAD_RET_TYPE void * # define THREAD_RET_CAST(p) ((void *)(p)) @@ -456,3 +461,7 @@ typedef struct condpair { #ifndef INIT_THREADS # define INIT_THREADS NOOP #endif + +#ifndef PTHREAD_ATFORK +# define PTHREAD_ATFORK(prepare,parent,child) NOOP +#endif diff --git a/win32/win32thread.h b/win32/win32thread.h index 1f8840c0c0..7105eca2e5 100644 --- a/win32/win32thread.h +++ b/win32/win32thread.h @@ -180,6 +180,8 @@ END_EXTERN_C TlsFree(PL_thr_key); \ } STMT_END +#define PTHREAD_ATFORK(prepare,parent,child) NOOP + #if defined(USE_RTL_THREAD_API) && !defined(_MSC_VER) #define JOIN(t, avp) \ STMT_START { \ |