summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2004-07-30 15:16:16 (GMT)
committerdgp <dgp@users.sourceforge.net>2004-07-30 15:16:16 (GMT)
commitd0904f7d806117d3dc163f4fde31933756306b74 (patch)
treefff45d82623a0bba5c672069b4ff0bf386f6ceb0
parent8cb60907ea6697c4c276a8814bee997e74909d2e (diff)
downloadtcl-d0904f7d806117d3dc163f4fde31933756306b74.zip
tcl-d0904f7d806117d3dc163f4fde31933756306b74.tar.gz
tcl-d0904f7d806117d3dc163f4fde31933756306b74.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]
-rw-r--r--ChangeLog6
-rw-r--r--generic/tclEvent.c48
2 files changed, 30 insertions, 24 deletions
diff --git a/ChangeLog b/ChangeLog
index 447c9ed..e01c52d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2004-07-30 Don Porter <dgp@users.sourceforge.net>
+
+ * 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]
+
2004-07-30 Daniel Steffen <das@users.sourceforge.net>
* unix/configure:
diff --git a/generic/tclEvent.c b/generic/tclEvent.c
index 187a6e3..bd4bfae 100644
--- a/generic/tclEvent.c
+++ b/generic/tclEvent.c
@@ -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: tclEvent.c,v 1.44 2004/07/21 01:45:44 hobbs Exp $
+ * RCS: @(#) $Id: tclEvent.c,v 1.45 2004/07/30 15:16:16 dgp Exp $
*/
#include "tclInt.h"
@@ -846,6 +846,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) {
@@ -859,29 +882,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.