From 6e55611be005b723e3f0d2ec521f2e73fce4c003 Mon Sep 17 00:00:00 2001 From: Joe Mistachkin Date: Mon, 28 Oct 2013 21:45:52 +0000 Subject: Try resetting all the 'one time' locks as well. --- generic/tclInt.h | 1 + unix/tclUnixNotfy.c | 8 ++++++++ unix/tclUnixThrd.c | 30 ++++++++++++++++++++++++++++++ win/tclWinThrd.c | 23 +++++++++++++++++++++++ 4 files changed, 62 insertions(+) diff --git a/generic/tclInt.h b/generic/tclInt.h index dc28b97..9ec4a55 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -2665,6 +2665,7 @@ MODULE_SCOPE int TclpThreadCreate(Tcl_ThreadId *idPtr, MODULE_SCOPE int TclpFindVariable(const char *name, int *lengthPtr); MODULE_SCOPE void TclpInitLibraryPath(char **valuePtr, int *lengthPtr, Tcl_Encoding *encodingPtr); +MODULE_SCOPE void TclpResetLocks(void); MODULE_SCOPE void TclpInitLock(void); MODULE_SCOPE void TclpInitPlatform(void); MODULE_SCOPE void TclpInitUnlock(void); diff --git a/unix/tclUnixNotfy.c b/unix/tclUnixNotfy.c index 4ce4840..2440b01 100644 --- a/unix/tclUnixNotfy.c +++ b/unix/tclUnixNotfy.c @@ -1370,6 +1370,14 @@ AtForkChildProc(void) notifierMutex = NULL; /* + * Next, forcibly reset all the "one time" locks used by the threading + * subsystem. This is necessary on some (all?) variants of Unix where + * the pthread internal state does not survive a call to fork(). + */ + + TclpResetLocks(); + + /* * Force the notifier subsystem to be initialized now. This should * create the notifier thread in this process. Subsequently, that new * thread will re-open the trigger pipe. diff --git a/unix/tclUnixThrd.c b/unix/tclUnixThrd.c index ad36242..04d736b 100644 --- a/unix/tclUnixThrd.c +++ b/unix/tclUnixThrd.c @@ -317,6 +317,36 @@ Tcl_GetCurrentThread(void) /* *---------------------------------------------------------------------- * + * TclpResetLocks + * + * This procedure is used to forcibly reset all the "one time" locks + * used by the other platform-specific locking procedures. Currently, + * this procedure is only called from the notifier to handle fork() + * and must not be called from anywhere else. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +void +TclpResetLocks(void) +{ +#ifdef TCL_THREADS + pthread_mutex_t dummyLock = PTHREAD_MUTEX_INITIALIZER; + memcpy((void *)&masterLock, (void *)&dummyLock, sizeof(pthread_mutex_t)); + memcpy((void *)&initLock, (void *)&dummyLock, sizeof(pthread_mutex_t)); + memcpy((void *)&allocLock, (void *)&dummyLock, sizeof(pthread_mutex_t)); +#endif +} + +/* + *---------------------------------------------------------------------- + * * TclpInitLock * * This procedure is used to grab a lock that serializes initialization diff --git a/win/tclWinThrd.c b/win/tclWinThrd.c index 2413a78..51d4d76 100644 --- a/win/tclWinThrd.c +++ b/win/tclWinThrd.c @@ -340,6 +340,29 @@ Tcl_GetCurrentThread(void) /* *---------------------------------------------------------------------- * + * TclpResetLocks + * + * This procedure is used to forcibly reset all the "one time" locks + * used by the other platform-specific locking procedures. Currently, + * this procedure does nothing and should not be called. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +void +TclpResetLocks(void) +{ +} + +/* + *---------------------------------------------------------------------- + * * TclpInitLock * * This procedure is used to grab a lock that serializes initialization -- cgit v0.12