summaryrefslogtreecommitdiffstats
path: root/unix/tclUnixNotfy.c
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2013-07-22 10:57:44 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2013-07-22 10:57:44 (GMT)
commita038288139470e7a32c1e711fcfdbd64212e87e4 (patch)
tree06dde2f69b720970ae28b8cfb0195ac37990253f /unix/tclUnixNotfy.c
parentf9820a2863b758aa1d07274355cd62f9ecbddae1 (diff)
downloadtcl-a038288139470e7a32c1e711fcfdbd64212e87e4.zip
tcl-a038288139470e7a32c1e711fcfdbd64212e87e4.tar.gz
tcl-a038288139470e7a32c1e711fcfdbd64212e87e4.tar.bz2
Use pthread_atfork() when available.
Diffstat (limited to 'unix/tclUnixNotfy.c')
-rw-r--r--unix/tclUnixNotfy.c90
1 files changed, 89 insertions, 1 deletions
diff --git a/unix/tclUnixNotfy.c b/unix/tclUnixNotfy.c
index 6e8b5fa..f414c3f 100644
--- a/unix/tclUnixNotfy.c
+++ b/unix/tclUnixNotfy.c
@@ -202,7 +202,13 @@ static Tcl_ThreadId notifierThread;
#ifdef TCL_THREADS
static void NotifierThreadProc(ClientData clientData);
-#endif
+#ifdef HAVE_PTHREAD_ATFORK
+static int atForkInit = 0;
+static void AtForkPrepare(void);
+static void AtForkParent(void);
+static void AtForkChild(void);
+#endif /* HAVE_PTHREAD_ATFORK */
+#endif /* TCL_THREADS */
static int FileHandlerEventProc(Tcl_Event *evPtr, int flags);
/*
@@ -276,6 +282,21 @@ Tcl_InitNotifier(void)
*/
Tcl_MutexLock(&notifierMutex);
+#ifdef HAVE_PTHREAD_ATFORK
+ /*
+ * Install pthread_atfork handlers to reinitialize the notifier in the
+ * child of a fork.
+ */
+
+ if (!atForkInit) {
+ int result = pthread_atfork(AtForkPrepare, AtForkParent, AtForkChild);
+
+ if (result) {
+ Tcl_Panic("Tcl_InitNotifier: pthread_atfork failed");
+ }
+ atForkInit = 1;
+ }
+#endif
/*
* Check if my process id changed, e.g. I was forked
* In this case, restart the notifier thread and close the
@@ -1251,6 +1272,73 @@ NotifierThreadProc(
TclpThreadExit (0);
}
+
+#ifdef HAVE_PTHREAD_ATFORK
+/*
+ *----------------------------------------------------------------------
+ *
+ * AtForkPrepare --
+ *
+ * Lock the notifier in preparation for a fork.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+AtForkPrepare(void)
+{
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * AtForkParent --
+ *
+ * Unlock the notifier in the parent after a fork.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+AtForkParent(void)
+{
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * AtForkChild --
+ *
+ * Unlock and reinstall the notifier in the child after a fork.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+AtForkChild(void)
+{
+ Tcl_InitNotifier();
+}
+#endif /* HAVE_PTHREAD_ATFORK */
+
#endif /* TCL_THREADS */
#endif /* HAVE_COREFOUNDATION */