diff options
| author | dgp@users.sourceforge.net <dgp> | 2004-07-30 15:16:16 (GMT) |
|---|---|---|
| committer | dgp@users.sourceforge.net <dgp> | 2004-07-30 15:16:16 (GMT) |
| commit | c22c0af0a4c19aa51bf2c430ed20b706bb59e986 (patch) | |
| tree | fff45d82623a0bba5c672069b4ff0bf386f6ceb0 /generic/tclEvent.c | |
| parent | b8323140ff25b6e8d00d9052b24e8cb1bf4805e7 (diff) | |
| download | tcl-c22c0af0a4c19aa51bf2c430ed20b706bb59e986.zip tcl-c22c0af0a4c19aa51bf2c430ed20b706bb59e986.tar.gz tcl-c22c0af0a4c19aa51bf2c430ed20b706bb59e986.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.c | 48 |
1 files changed, 24 insertions, 24 deletions
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. |
