diff options
author | vasiljevic <zv@archiware.com> | 2006-07-11 13:18:10 (GMT) |
---|---|---|
committer | vasiljevic <zv@archiware.com> | 2006-07-11 13:18:10 (GMT) |
commit | b21d03a76b28dee1c88a2ccc05dd815364babd83 (patch) | |
tree | 6611a81931711753b47223fc8421f578b5df517e | |
parent | 03cfbaf3dcd8848bcc9b3add4e8f78f34bbb5398 (diff) | |
download | tcl-b21d03a76b28dee1c88a2ccc05dd815364babd83.zip tcl-b21d03a76b28dee1c88a2ccc05dd815364babd83.tar.gz tcl-b21d03a76b28dee1c88a2ccc05dd815364babd83.tar.bz2 |
Made Tcl_AsyncDelete() more tolerant when called after all thread TSD
has been garbage-collected.
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | generic/tclAsync.c | 37 |
2 files changed, 28 insertions, 14 deletions
@@ -1,3 +1,8 @@ +2006-07-11 Zoran Vasiljevic <vasiljevic@users.sourceforge.net> + + * generic/tclAsync.c: Made Tcl_AsyncDelete() more tolerant + when called after all thread TSD has been garbage-collected. + 2006-07-10 Jeff Hobbs <jeffh@ActiveState.com> * generic/tclIO.c (Tcl_CreateChannel): allow Tcl std channel diff --git a/generic/tclAsync.c b/generic/tclAsync.c index 76e3e28..c99cea9 100644 --- a/generic/tclAsync.c +++ b/generic/tclAsync.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: tclAsync.c,v 1.6 2001/08/30 07:50:18 davygrvy Exp $ + * RCS: @(#) $Id: tclAsync.c,v 1.6.12.1 2006/07/11 13:18:10 vasiljevic Exp $ */ #include "tclInt.h" @@ -286,20 +286,29 @@ Tcl_AsyncDelete(async) AsyncHandler *asyncPtr = (AsyncHandler *) async; AsyncHandler *prevPtr; + /* + * Conservatively check the existence of the linked list of + * registered handlers, as we may come at this point even + * when the TSD's for the current thread have been already + * garbage-collected. + */ + Tcl_MutexLock(&tsdPtr->asyncMutex); - if (tsdPtr->firstHandler == asyncPtr) { - tsdPtr->firstHandler = asyncPtr->nextPtr; - if (tsdPtr->firstHandler == NULL) { - tsdPtr->lastHandler = NULL; - } - } else { - prevPtr = tsdPtr->firstHandler; - while (prevPtr->nextPtr != asyncPtr) { - prevPtr = prevPtr->nextPtr; - } - prevPtr->nextPtr = asyncPtr->nextPtr; - if (tsdPtr->lastHandler == asyncPtr) { - tsdPtr->lastHandler = prevPtr; + if (tsdPtr->firstHandler != NULL ) { + if (tsdPtr->firstHandler == asyncPtr) { + tsdPtr->firstHandler = asyncPtr->nextPtr; + if (tsdPtr->firstHandler == NULL) { + tsdPtr->lastHandler = NULL; + } + } else { + prevPtr = tsdPtr->firstHandler; + while (prevPtr->nextPtr != asyncPtr) { + prevPtr = prevPtr->nextPtr; + } + prevPtr->nextPtr = asyncPtr->nextPtr; + if (tsdPtr->lastHandler == asyncPtr) { + tsdPtr->lastHandler = prevPtr; + } } } Tcl_MutexUnlock(&tsdPtr->asyncMutex); |