diff options
author | dgp <dgp@users.sourceforge.net> | 2003-03-21 03:23:23 (GMT) |
---|---|---|
committer | dgp <dgp@users.sourceforge.net> | 2003-03-21 03:23:23 (GMT) |
commit | a0ed5880ee97954af162748411d3a6e692b29d7f (patch) | |
tree | 0c5cc36fcf18b16e588c47d9dee6ca5fd1a68dbc | |
parent | 4ade466c44615be091e19c177e11eef5524163c4 (diff) | |
download | tcl-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-- | ChangeLog | 14 | ||||
-rw-r--r-- | generic/tclInt.h | 3 | ||||
-rw-r--r-- | generic/tclStubInit.c | 25 | ||||
-rw-r--r-- | mac/tclMacNotify.c | 7 | ||||
-rw-r--r-- | unix/tclUnixNotfy.c | 11 | ||||
-rw-r--r-- | win/tclWinNotify.c | 8 |
6 files changed, 55 insertions, 13 deletions
@@ -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); } |