summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2003-03-21 03:23:23 (GMT)
committerdgp <dgp@users.sourceforge.net>2003-03-21 03:23:23 (GMT)
commita0ed5880ee97954af162748411d3a6e692b29d7f (patch)
tree0c5cc36fcf18b16e588c47d9dee6ca5fd1a68dbc
parent4ade466c44615be091e19c177e11eef5524163c4 (diff)
downloadtcl-a0ed5880ee97954af162748411d3a6e692b29d7f.zip
tcl-a0ed5880ee97954af162748411d3a6e692b29d7f.tar.gz
tcl-a0ed5880ee97954af162748411d3a6e692b29d7f.tar.bz2
* 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]
-rw-r--r--ChangeLog14
-rw-r--r--generic/tclInt.h3
-rw-r--r--generic/tclStubInit.c25
-rw-r--r--mac/tclMacNotify.c7
-rw-r--r--unix/tclUnixNotfy.c11
-rw-r--r--win/tclWinNotify.c8
6 files changed, 55 insertions, 13 deletions
diff --git a/ChangeLog b/ChangeLog
index 1d47a00..7271e67 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 4ee4b5b..af2bf4e 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.121 2003/03/20 22:33:44 dgp Exp $
+ * RCS: @(#) $Id: tclInt.h,v 1.122 2003/03/21 03:23:24 dgp Exp $
*/
#ifndef _TCLINT
@@ -1542,6 +1542,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..9bf6c73 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.80 2003/03/21 03:23:24 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..f2704be 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.9 2003/03/21 03:23:24 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..11b30fb 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.12 2003/03/21 03:23:24 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..8cf4c4c 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.12 2003/03/21 03:23:24 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);
}