summaryrefslogtreecommitdiffstats
path: root/generic/tkImage.c
diff options
context:
space:
mode:
authordkf <donal.k.fellows@manchester.ac.uk>2003-07-07 09:35:58 (GMT)
committerdkf <donal.k.fellows@manchester.ac.uk>2003-07-07 09:35:58 (GMT)
commitbac92cbfb391c2766bfaed11eb16bd73abbed30a (patch)
tree28e76c61cbbb84e75a216aa101a50252613c0367 /generic/tkImage.c
parent1efd22b091f8908cded939bc3ba75ab14019299b (diff)
downloadtk-bac92cbfb391c2766bfaed11eb16bd73abbed30a.zip
tk-bac92cbfb391c2766bfaed11eb16bd73abbed30a.tar.gz
tk-bac92cbfb391c2766bfaed11eb16bd73abbed30a.tar.bz2
Fixed [Bug 749353] by making the removal of masters from the global image table
aggressive when the interp is being deleted, and making the deletion code always check to see whether it should actually be deleting an entry or not. No tests as it comes under the heading of crash-on-bug, and the bug is not easy to excite (it requires a full script and interpreter deletion with lots of events about.)
Diffstat (limited to 'generic/tkImage.c')
-rw-r--r--generic/tkImage.c28
1 files changed, 21 insertions, 7 deletions
diff --git a/generic/tkImage.c b/generic/tkImage.c
index 651c675..a27a446 100644
--- a/generic/tkImage.c
+++ b/generic/tkImage.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: tkImage.c,v 1.20 2003/05/08 09:35:41 dkf Exp $
+ * RCS: @(#) $Id: tkImage.c,v 1.21 2003/07/07 09:35:58 dkf Exp $
*/
#include "tkInt.h"
@@ -87,7 +87,8 @@ static Tcl_ThreadDataKey dataKey;
*/
static void DeleteImage _ANSI_ARGS_((ImageMaster *masterPtr));
-static void EventuallyDeleteImage _ANSI_ARGS_((ImageMaster *masterPtr));
+static void EventuallyDeleteImage _ANSI_ARGS_((ImageMaster *masterPtr,
+ int forgetImageHashNow));
/*
*----------------------------------------------------------------------
@@ -317,7 +318,7 @@ Tk_ImageObjCmd(clientData, interp, objc, objv)
if ((*typePtr->createProc)(interp, name, objc,
args, typePtr, (Tk_ImageMaster) masterPtr,
&masterPtr->masterData) != TCL_OK) {
- EventuallyDeleteImage(masterPtr);
+ EventuallyDeleteImage(masterPtr, 0);
Tcl_Release((ClientData) masterPtr);
if (oldimage) {
ckfree((char *) args);
@@ -553,6 +554,9 @@ Tk_NameOfImage(imageMaster)
{
ImageMaster *masterPtr = (ImageMaster *) imageMaster;
+ if (masterPtr->hPtr == NULL) {
+ return NULL;
+ }
return Tcl_GetHashKey(masterPtr->tablePtr, masterPtr->hPtr);
}
@@ -677,7 +681,10 @@ Tk_FreeImage(image)
*/
if ((masterPtr->typePtr == NULL) && (masterPtr->instancePtr == NULL)) {
- Tcl_DeleteHashEntry(masterPtr->hPtr);
+ if (masterPtr->hPtr != NULL) {
+ Tcl_DeleteHashEntry(masterPtr->hPtr);
+ }
+ Tcl_Release((ClientData) masterPtr->winPtr);
ckfree((char *) masterPtr);
}
}
@@ -952,7 +959,9 @@ DeleteImage(masterPtr)
(*typePtr->deleteProc)(masterPtr->masterData);
}
if (masterPtr->instancePtr == NULL) {
- Tcl_DeleteHashEntry(masterPtr->hPtr);
+ if (masterPtr->hPtr != NULL) {
+ Tcl_DeleteHashEntry(masterPtr->hPtr);
+ }
Tcl_Release((ClientData) masterPtr->winPtr);
ckfree((char *) masterPtr);
} else {
@@ -979,9 +988,14 @@ DeleteImage(masterPtr)
*/
static void
-EventuallyDeleteImage(masterPtr)
+EventuallyDeleteImage(masterPtr, forgetImageHashNow)
ImageMaster *masterPtr; /* Pointer to main data structure for image. */
+ int forgetImageHashNow; /* Flag to say whether the hash table is
+ * about to vanish. */
{
+ if (forgetImageHashNow) {
+ masterPtr->hPtr = NULL;
+ }
if (!masterPtr->deleted) {
masterPtr->deleted = 1;
Tcl_EventuallyFree((ClientData) masterPtr,
@@ -1018,7 +1032,7 @@ TkDeleteAllImages(mainPtr)
for (hPtr = Tcl_FirstHashEntry(&mainPtr->imageTable, &search);
hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
- EventuallyDeleteImage((ImageMaster *) Tcl_GetHashValue(hPtr));
+ EventuallyDeleteImage((ImageMaster *) Tcl_GetHashValue(hPtr), 1);
}
Tcl_DeleteHashTable(&mainPtr->imageTable);
}