Tcl Source Code

Artifact [76b2929589]
Login

Artifact 76b2929589c5fbd776b78bcf5dd776de1d5d30a0:

Attachment "tclMacOSXNotify-atfork_HEAD.patch" to ticket [923072ffff] added by das 2006-05-27 12:26:27.
Index: macosx/tclMacOSXNotify.c
===================================================================
RCS file: /cvsroot/tcl/tcl/macosx/tclMacOSXNotify.c,v
retrieving revision 1.6
diff -u -p -w -b -r1.6 tclMacOSXNotify.c
--- macosx/tclMacOSXNotify.c	27 Nov 2005 02:33:49 -0000	1.6
+++ macosx/tclMacOSXNotify.c	27 May 2006 03:29:09 -0000
@@ -217,6 +217,13 @@ static pthread_t notifierThread;
 static void	NotifierThreadProc(ClientData clientData);
 static int	FileHandlerEventProc(Tcl_Event *evPtr, int flags);
 
+#ifdef HAVE_PTHREAD_ATFORK
+static int	atForkInit = 0;
+static void	AtForkPrepare(void);
+static void	AtForkParent(void);
+static void	AtForkChild(void);
+#endif
+
 /*
  *----------------------------------------------------------------------
  *
@@ -265,6 +272,20 @@ Tcl_InitNotifier(void)
      */
 
     LOCK_NOTIFIER_INIT;
+#ifdef HAVE_PTHREAD_ATFORK
+    /*
+     * Install pthread_atfork handlers to reinstall the notifier thread 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
     if (notifierCount == 0) {
 	int fds[2], status, result;
 	pthread_attr_t attr;
@@ -1058,6 +1079,94 @@ NotifierThreadProc(
     }
     pthread_exit (0);
 }
+
+#ifdef HAVE_PTHREAD_ATFORK
+/*
+ *----------------------------------------------------------------------
+ *
+ * AtForkPrepare --
+ *
+ *	Lock the notifier in preparation for a fork.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+AtForkPrepare(void)
+{
+    LOCK_NOTIFIER_INIT;
+    LOCK_NOTIFIER;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * AtForkParent --
+ *
+ *	Unlock the notifier in the parent after a fork.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+AtForkParent(void)
+{
+    UNLOCK_NOTIFIER;
+    UNLOCK_NOTIFIER_INIT;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * AtForkChild --
+ *
+ *	Unlock and reinstall the notifier in the child after a fork.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+AtForkChild(void)
+{
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    UNLOCK_NOTIFIER;
+    UNLOCK_NOTIFIER_INIT;
+    if (tsdPtr->runLoop) {
+	tsdPtr->runLoop = NULL;
+	CFRunLoopSourceInvalidate(tsdPtr->runLoopSource);
+	CFRelease(tsdPtr->runLoopSource);
+	tsdPtr->runLoopSource = NULL;
+    }
+    if (notifierCount > 0) {
+	notifierCount = 0;
+	/* Note that Tcl_FinalizeNotifier does not use its clientData
+	 * parameter, so discard return value of Tcl_InitNotifier here and
+	 * leave stale clientData in tclNotify.c's ThreadSpecificData.
+	 */
+	Tcl_InitNotifier();
+    }
+}
+#endif /* HAVE_PTHREAD_ATFORK */
+
 #endif /* HAVE_COREFOUNDATION */
 
 /*
Index: unix/tcl.m4
===================================================================
RCS file: /cvsroot/tcl/tcl/unix/tcl.m4,v
retrieving revision 1.167
diff -u -p -w -b -r1.167 tcl.m4
--- unix/tcl.m4	24 May 2006 10:37:20 -0000	1.167
+++ unix/tcl.m4	27 May 2006 03:29:10 -0000
@@ -1617,10 +1617,11 @@ dnl AC_CHECK_TOOL(AR, ar)
                     LIBS="$LIBS -framework CoreFoundation"
                     AC_DEFINE(HAVE_COREFOUNDATION, 1, 
                         [Do we have access to Darwin CoreFoundation.framework ?])
-                fi
-	    fi
 	    AC_CHECK_HEADERS(libkern/OSAtomic.h)
 	    AC_CHECK_FUNCS(OSSpinLockLock)
+		    AC_CHECK_FUNCS(pthread_atfork)
+		fi
+	    fi
 	    AC_CHECK_HEADERS(copyfile.h)
 	    AC_CHECK_FUNCS(copyfile)
 	    AC_DEFINE(MAC_OSX_TCL, 1, [Is this a Mac I see before me?])