From 7397eb21b5546e2f2db642b3a7fda20d24bfd70b Mon Sep 17 00:00:00 2001
From: dgp <dgp@users.sourceforge.net>
Date: Fri, 21 Mar 2003 03:24:08 +0000
Subject:         * generic/tclInt.h (tclOriginalNotifier):         *
 generic/tclStubInit.c (tclOriginalNotifier):         * mac/tclMacNotify.c
 (Tcl_SetTimer,Tcl_WaitForEvent):         * unix/tclUnixNotfy.c
 (Tcl_SetTimer,Tcl_WaitForEvent,                
 Tcl_CreateFileHandler,Tcl_DeleteFileHandler):         * win/tclWinNotify.c
 (Tcl_SetTimer,Tcl_WaitForEvent):  Some linkers         apparently use a
 different representation for a pointer to a function         within the same
 compilation unit and a pointer to a function in a         different
 compilation unit.  This causes checks like those in the         original
 notifier procedures to fall into infinite loops.  The fix         is to store
 pointers to the original notifier procedures in a struct         defined in
 the same compilation unit as the stubs tables, and compare         against
 those values.  [Bug 707174]

---
 ChangeLog             | 14 ++++++++++++++
 generic/tclInt.h      |  3 ++-
 generic/tclStubInit.c | 25 ++++++++++++++++++++++++-
 mac/tclMacNotify.c    |  7 ++++---
 unix/tclUnixNotfy.c   | 11 ++++++-----
 win/tclWinNotify.c    |  8 +++++---
 6 files changed, 55 insertions(+), 13 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 182e6e3..95cbae6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,19 @@
 2003-03-20  Don Porter  <dgp@users.sourceforge.net>
 
+        * generic/tclInt.h (tclOriginalNotifier):
+        * generic/tclStubInit.c (tclOriginalNotifier):
+        * mac/tclMacNotify.c (Tcl_SetTimer,Tcl_WaitForEvent):
+        * unix/tclUnixNotfy.c (Tcl_SetTimer,Tcl_WaitForEvent,
+                Tcl_CreateFileHandler,Tcl_DeleteFileHandler):
+        * win/tclWinNotify.c (Tcl_SetTimer,Tcl_WaitForEvent):  Some linkers
+        apparently use a different representation for a pointer to a function
+        within the same compilation unit and a pointer to a function in a
+        different compilation unit.  This causes checks like those in the
+        original notifier procedures to fall into infinite loops.  The fix
+        is to store pointers to the original notifier procedures in a struct
+        defined in the same compilation unit as the stubs tables, and compare
+        against those values.  [Bug 707174]
+
 	* generic/tclInt.h:  Removed definition of ParseValue struct that
 	is no longer used.
 
diff --git a/generic/tclInt.h b/generic/tclInt.h
index fcddd10..077c65b 100644
--- a/generic/tclInt.h
+++ b/generic/tclInt.h
@@ -12,7 +12,7 @@
  * See the file "license.terms" for information on usage and redistribution
  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  *
- * RCS: @(#) $Id: tclInt.h,v 1.118.2.1 2003/03/20 22:33:02 dgp Exp $
+ * RCS: @(#) $Id: tclInt.h,v 1.118.2.2 2003/03/21 03:24:08 dgp Exp $
  */
 
 #ifndef _TCLINT
@@ -1546,6 +1546,7 @@ extern char *			tclDefaultEncodingDir;
 extern Tcl_ChannelType		tclFileChannelType;
 extern char *			tclMemDumpFileName;
 extern TclPlatformType		tclPlatform;
+extern Tcl_NotifierProcs	tclOriginalNotifier;
 
 /*
  * Variables denoting the Tcl object types defined in the core.
diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c
index f303e0a..f70c479 100644
--- a/generic/tclStubInit.c
+++ b/generic/tclStubInit.c
@@ -8,7 +8,7 @@
  * See the file "license.terms" for information on usage and redistribution
  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  *
- * RCS: @(#) $Id: tclStubInit.c,v 1.79 2003/02/18 02:25:45 hobbs Exp $
+ * RCS: @(#) $Id: tclStubInit.c,v 1.79.2.1 2003/03/21 03:24:08 dgp Exp $
  */
 
 #include "tclInt.h"
@@ -37,6 +37,29 @@
 #endif
 
 /*
+ * Keep a record of the original Notifier procedures, created in the
+ * same compilation unit as the stub tables so we can later do reliable,
+ * portable comparisons to see whether a Tcl_SetNotifier() call swapped
+ * new routines into the stub table.
+ */
+
+Tcl_NotifierProcs tclOriginalNotifier = {
+    Tcl_SetTimer,
+    Tcl_WaitForEvent,
+#if !defined(__WIN32__) && !defined(MAC_TCL) /* UNIX */
+    Tcl_CreateFileHandler,
+    Tcl_DeleteFileHandler,
+#else
+    NULL,
+    NULL,
+#endif
+    NULL,
+    NULL,
+    NULL,
+    NULL
+};
+
+/*
  * WARNING: The contents of this file is automatically generated by the
  * tools/genStubs.tcl script. Any modifications to the function declarations
  * below should be made in the generic/tcl.decls script.
diff --git a/mac/tclMacNotify.c b/mac/tclMacNotify.c
index f27645e..81f4082 100644
--- a/mac/tclMacNotify.c
+++ b/mac/tclMacNotify.c
@@ -14,7 +14,7 @@
  * See the file "license.terms" for information on usage and redistribution
  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  *
- * RCS: @(#) $Id: tclMacNotify.c,v 1.8 2001/11/23 01:27:53 das Exp $
+ * RCS: @(#) $Id: tclMacNotify.c,v 1.8.4.1 2003/03/21 03:24:08 dgp Exp $
  */
 
 #include "tclInt.h"
@@ -48,6 +48,7 @@ extern pascal QHdrPtr GetEventQueue(void)
  */
  
 extern TclStubs tclStubs;
+extern Tcl_NotifierProcs tclOriginalNotifier;
 
 /*
  * The follwing static indicates whether this module has been initialized.
@@ -339,7 +340,7 @@ Tcl_SetTimer(
      * on the Mac, but mirrors the UNIX hook.
      */
 
-    if (tclStubs.tcl_SetTimer != Tcl_SetTimer) {
+    if (tclStubs.tcl_SetTimer != tclOriginalNotifier.setTimerProc) {
 	tclStubs.tcl_SetTimer(timePtr);
 	return;
     }
@@ -420,7 +421,7 @@ Tcl_WaitForEvent(
      * sense on the Mac, but mirrors the UNIX hook.
      */
 
-    if (tclStubs.tcl_WaitForEvent != Tcl_WaitForEvent) {
+    if (tclStubs.tcl_WaitForEvent != tclOriginalNotifier.waitForEventProc) {
 	return tclStubs.tcl_WaitForEvent(timePtr);
     }
 
diff --git a/unix/tclUnixNotfy.c b/unix/tclUnixNotfy.c
index 94be5a0..7de3417 100644
--- a/unix/tclUnixNotfy.c
+++ b/unix/tclUnixNotfy.c
@@ -11,7 +11,7 @@
  * See the file "license.terms" for information on usage and redistribution
  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  *
- * RCS: @(#) $Id: tclUnixNotfy.c,v 1.11 2002/08/31 06:09:46 das Exp $
+ * RCS: @(#) $Id: tclUnixNotfy.c,v 1.11.2.1 2003/03/21 03:24:09 dgp Exp $
  */
 
 #include "tclInt.h"
@@ -19,6 +19,7 @@
 #include <signal.h> 
 
 extern TclStubs tclStubs;
+extern Tcl_NotifierProcs tclOriginalNotifier;
 
 /*
  * This structure is used to keep track of the notifier info for a 
@@ -353,7 +354,7 @@ Tcl_SetTimer(timePtr)
      * timeout values to Tcl_WaitForEvent.
      */
 
-    if (tclStubs.tcl_SetTimer != Tcl_SetTimer) {
+    if (tclStubs.tcl_SetTimer != tclOriginalNotifier.setTimerProc) {
 	tclStubs.tcl_SetTimer(timePtr);
     }
 }
@@ -412,7 +413,7 @@ Tcl_CreateFileHandler(fd, mask, proc, clientData)
     FileHandler *filePtr;
     int index, bit;
 
-    if (tclStubs.tcl_CreateFileHandler != Tcl_CreateFileHandler) {
+    if (tclStubs.tcl_CreateFileHandler != tclOriginalNotifier.createFileHandlerProc) {
 	tclStubs.tcl_CreateFileHandler(fd, mask, proc, clientData);
 	return;
     }
@@ -486,7 +487,7 @@ Tcl_DeleteFileHandler(fd)
     unsigned long flags;
     ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
 
-    if (tclStubs.tcl_DeleteFileHandler != Tcl_DeleteFileHandler) {
+    if (tclStubs.tcl_DeleteFileHandler != tclOriginalNotifier.deleteFileHandlerProc) {
 	tclStubs.tcl_DeleteFileHandler(fd);
 	return;
     }
@@ -662,7 +663,7 @@ Tcl_WaitForEvent(timePtr)
 #endif
     ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
 
-    if (tclStubs.tcl_WaitForEvent != Tcl_WaitForEvent) {
+    if (tclStubs.tcl_WaitForEvent != tclOriginalNotifier.waitForEventProc) {
 	return tclStubs.tcl_WaitForEvent(timePtr);
     }
 
diff --git a/win/tclWinNotify.c b/win/tclWinNotify.c
index b7bb17d..e6fca31 100644
--- a/win/tclWinNotify.c
+++ b/win/tclWinNotify.c
@@ -10,7 +10,7 @@
  * See the file "license.terms" for information on usage and redistribution
  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  *
- * RCS: @(#) $Id: tclWinNotify.c,v 1.11 2003/01/16 19:02:00 mdejong Exp $
+ * RCS: @(#) $Id: tclWinNotify.c,v 1.11.2.1 2003/03/21 03:24:09 dgp Exp $
  */
 
 #include "tclWinInt.h"
@@ -45,6 +45,8 @@ typedef struct ThreadSpecificData {
 static Tcl_ThreadDataKey dataKey;
 
 extern TclStubs tclStubs;
+extern Tcl_NotifierProcs tclOriginalNotifier;
+
 /*
  * The following static indicates the number of threads that have
  * initialized notifiers.  It controls the lifetime of the TclNotifier
@@ -267,7 +269,7 @@ Tcl_SetTimer(
      * on Windows, but mirrors the UNIX hook.
      */
 
-    if (tclStubs.tcl_SetTimer != Tcl_SetTimer) {
+    if (tclStubs.tcl_SetTimer != tclOriginalNotifier.setTimerProc) {
 	tclStubs.tcl_SetTimer(timePtr);
 	return;
     }
@@ -433,7 +435,7 @@ Tcl_WaitForEvent(
      * sense on windows, but mirrors the UNIX hook.
      */
 
-    if (tclStubs.tcl_WaitForEvent != Tcl_WaitForEvent) {
+    if (tclStubs.tcl_WaitForEvent != tclOriginalNotifier.waitForEventProc) {
 	return tclStubs.tcl_WaitForEvent(timePtr);
     }
 
-- 
cgit v0.12