summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoe Mistachkin <joe@mistachkin.com>2013-10-28 21:45:52 (GMT)
committerJoe Mistachkin <joe@mistachkin.com>2013-10-28 21:45:52 (GMT)
commit6e55611be005b723e3f0d2ec521f2e73fce4c003 (patch)
tree56c68a28ffaecd5d1afdcf53b25a2e1cd08f76d1
parent5399cdf3b1ddf72ac37efa3b23117cd69836552a (diff)
downloadtcl-6e55611be005b723e3f0d2ec521f2e73fce4c003.zip
tcl-6e55611be005b723e3f0d2ec521f2e73fce4c003.tar.gz
tcl-6e55611be005b723e3f0d2ec521f2e73fce4c003.tar.bz2
Try resetting all the 'one time' locks as well.
-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