From 7397eb21b5546e2f2db642b3a7fda20d24bfd70b Mon Sep 17 00:00:00 2001 From: dgp 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 + * 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 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