summaryrefslogtreecommitdiffstats
path: root/generic/tclEvent.c
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2004-07-30 15:15:56 (GMT)
committerdgp <dgp@users.sourceforge.net>2004-07-30 15:15:56 (GMT)
commit0d4f56abe1514bf10eabc9127af7a809f2d29ccd (patch)
tree751f4567ea51280277b692b9b97dc0a27ab0707f /generic/tclEvent.c
parentd09c5183cfcf8afb29ff58839fbb7b1925ccdb6a (diff)
downloadtcl-0d4f56abe1514bf10eabc9127af7a809f2d29ccd.zip
tcl-0d4f56abe1514bf10eabc9127af7a809f2d29ccd.tar.gz
tcl-0d4f56abe1514bf10eabc9127af7a809f2d29ccd.tar.bz2
* generic/tclEvent.c (Tcl_Finalize): Re-organized Tcl_Finalize
so that Tcl_ExitProc's that call Tcl_Finalize recursively do not cause deadlock. [Patch 999084 fixes Tk Bug 714956]
Diffstat (limited to 'generic/tclEvent.c')
-rw-r--r--generic/tclEvent.c48
1 files changed, 24 insertions, 24 deletions
diff --git a/generic/tclEvent.c b/generic/tclEvent.c
index 67ec728..059871c 100644
--- a/generic/tclEvent.c
+++ b/generic/tclEvent.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: tclEvent.c,v 1.28.2.8 2004/07/21 01:30:57 hobbs Exp $
+ * RCS: @(#) $Id: tclEvent.c,v 1.28.2.9 2004/07/30 15:15:57 dgp Exp $
*/
#include "tclInt.h"
@@ -783,6 +783,29 @@ void
Tcl_Finalize()
{
ExitHandler *exitPtr;
+
+ /*
+ * Invoke exit handlers first.
+ */
+
+ Tcl_MutexLock(&exitMutex);
+ inFinalize = 1;
+ for (exitPtr = firstExitPtr; exitPtr != NULL; exitPtr = firstExitPtr) {
+ /*
+ * Be careful to remove the handler from the list before
+ * invoking its callback. This protects us against
+ * double-freeing if the callback should call
+ * Tcl_DeleteExitHandler on itself.
+ */
+
+ firstExitPtr = exitPtr->nextPtr;
+ Tcl_MutexUnlock(&exitMutex);
+ (*exitPtr->proc)(exitPtr->clientData);
+ ckfree((char *) exitPtr);
+ Tcl_MutexLock(&exitMutex);
+ }
+ firstExitPtr = NULL;
+ Tcl_MutexUnlock(&exitMutex);
TclpInitLock();
if (subsystemsInitialized != 0) {
@@ -796,29 +819,6 @@ Tcl_Finalize()
(void) TCL_TSD_INIT(&dataKey);
/*
- * Invoke exit handlers first.
- */
-
- Tcl_MutexLock(&exitMutex);
- inFinalize = 1;
- for (exitPtr = firstExitPtr; exitPtr != NULL; exitPtr = firstExitPtr) {
- /*
- * Be careful to remove the handler from the list before
- * invoking its callback. This protects us against
- * double-freeing if the callback should call
- * Tcl_DeleteExitHandler on itself.
- */
-
- firstExitPtr = exitPtr->nextPtr;
- Tcl_MutexUnlock(&exitMutex);
- (*exitPtr->proc)(exitPtr->clientData);
- ckfree((char *) exitPtr);
- Tcl_MutexLock(&exitMutex);
- }
- firstExitPtr = NULL;
- Tcl_MutexUnlock(&exitMutex);
-
- /*
* Clean up after the current thread now, after exit handlers.
* In particular, the testexithandler command sets up something
* that writes to standard output, which gets closed.