summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--generic/tclInt.h1
-rw-r--r--unix/tclUnixNotfy.c8
-rw-r--r--unix/tclUnixThrd.c30
-rw-r--r--win/tclWinThrd.c23
4 files changed, 62 insertions, 0 deletions
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