diff options
author | nijtmans <nijtmans> | 2008-11-19 00:37:35 (GMT) |
---|---|---|
committer | nijtmans <nijtmans> | 2008-11-19 00:37:35 (GMT) |
commit | 8d02f3eefb3c880f59c76afb60f1e0fd64c77d0f (patch) | |
tree | 36b02c8bfa575ab7256c4fe4b6bf34b3194c8490 /generic | |
parent | af6b3cd3e4c83b73e3c84cfd656bffd05523d141 (diff) | |
download | tk-8d02f3eefb3c880f59c76afb60f1e0fd64c77d0f.zip tk-8d02f3eefb3c880f59c76afb60f1e0fd64c77d0f.tar.gz tk-8d02f3eefb3c880f59c76afb60f1e0fd64c77d0f.tar.bz2 |
Relax the constraint that every Tk_ImageType
can only be passed to Tk_CreateImageType once.
This allows tkImg to be loaded in multiple
interpreters in a thread-enabled build of Tk.
[Bug 2312027]
Diffstat (limited to 'generic')
-rw-r--r-- | generic/tkImage.c | 77 | ||||
-rw-r--r-- | generic/tkImgPhoto.c | 16 |
2 files changed, 68 insertions, 25 deletions
diff --git a/generic/tkImage.c b/generic/tkImage.c index 4dd3010..f043277 100644 --- a/generic/tkImage.c +++ b/generic/tkImage.c @@ -10,7 +10,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.35 2007/12/13 15:24:14 dgp Exp $ + * RCS: @(#) $Id: tkImage.c,v 1.35.2.1 2008/11/19 00:37:35 nijtmans Exp $ */ #include "tkInt.h" @@ -74,6 +74,8 @@ typedef struct ThreadSpecificData { Tk_ImageType *oldImageTypeList; /* First in a list of all known old-style * image types. */ + int initialized; /* Set to 1 if we've initialized the + * structure. */ } ThreadSpecificData; static Tcl_ThreadDataKey dataKey; @@ -81,6 +83,7 @@ static Tcl_ThreadDataKey dataKey; * Prototypes for local functions: */ +static void ImageTypeThreadExitProc(ClientData clientData); static void DeleteImage(ImageMaster *masterPtr); static void EventuallyDeleteImage(ImageMaster *masterPtr, int forgetImageHashNow); @@ -88,6 +91,42 @@ static void EventuallyDeleteImage(ImageMaster *masterPtr, /* *---------------------------------------------------------------------- * + * ImageTypeThreadExitProc -- + * + * Clean up the registered list of image types. + * + * Results: + * None. + * + * Side effects: + * The thread's linked lists of photo image formats is deleted. + * + *---------------------------------------------------------------------- + */ + +static void +ImageTypeThreadExitProc( + ClientData clientData) /* not used */ +{ + Tk_ImageType *freePtr; + ThreadSpecificData *tsdPtr = + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + + while (tsdPtr->oldImageTypeList != NULL) { + freePtr = tsdPtr->oldImageTypeList; + tsdPtr->oldImageTypeList = tsdPtr->oldImageTypeList->nextPtr; + ckfree((char *) freePtr); + } + while (tsdPtr->imageTypeList != NULL) { + freePtr = tsdPtr->imageTypeList; + tsdPtr->imageTypeList = tsdPtr->imageTypeList->nextPtr; + ckfree((char *) freePtr); + } +} + +/* + *---------------------------------------------------------------------- + * * Tk_CreateOldImageType, Tk_CreateImageType -- * * This function is invoked by an image manager to tell Tk about a new @@ -108,28 +147,40 @@ void Tk_CreateOldImageType( Tk_ImageType *typePtr) /* Structure describing the type. All of the * fields except "nextPtr" must be filled in - * by caller. Must not have been passed to - * Tk_CreateImageType previously. */ + * by caller. */ { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + Tk_ImageType *copyPtr; + ThreadSpecificData *tsdPtr = + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - typePtr->nextPtr = tsdPtr->oldImageTypeList; - tsdPtr->oldImageTypeList = typePtr; + if (!tsdPtr->initialized) { + tsdPtr->initialized = 1; + Tcl_CreateThreadExitHandler(ImageTypeThreadExitProc, NULL); + } + copyPtr = (Tk_ImageType *) ckalloc(sizeof(Tk_ImageType)); + *copyPtr = *typePtr; + copyPtr->nextPtr = tsdPtr->oldImageTypeList; + tsdPtr->oldImageTypeList = copyPtr; } void Tk_CreateImageType( Tk_ImageType *typePtr) /* Structure describing the type. All of the * fields except "nextPtr" must be filled in - * by caller. Must not have been passed to - * Tk_CreateImageType previously. */ + * by caller. */ { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + Tk_ImageType *copyPtr; + ThreadSpecificData *tsdPtr = + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - typePtr->nextPtr = tsdPtr->imageTypeList; - tsdPtr->imageTypeList = typePtr; + if (!tsdPtr->initialized) { + tsdPtr->initialized = 1; + Tcl_CreateThreadExitHandler(ImageTypeThreadExitProc, NULL); + } + copyPtr = (Tk_ImageType *) ckalloc(sizeof(Tk_ImageType)); + *copyPtr = *typePtr; + copyPtr->nextPtr = tsdPtr->imageTypeList; + tsdPtr->imageTypeList = copyPtr; } /* diff --git a/generic/tkImgPhoto.c b/generic/tkImgPhoto.c index eff0fde..c9acc4d 100644 --- a/generic/tkImgPhoto.c +++ b/generic/tkImgPhoto.c @@ -17,7 +17,7 @@ * Department of Computer Science, * Australian National University. * - * RCS: @(#) $Id: tkImgPhoto.c,v 1.76 2007/12/13 15:24:14 dgp Exp $ + * RCS: @(#) $Id: tkImgPhoto.c,v 1.76.2.1 2008/11/19 00:37:35 nijtmans Exp $ */ #include "tkInt.h" @@ -473,13 +473,11 @@ PhotoFormatThreadExitProc( while (tsdPtr->oldFormatList != NULL) { freePtr = tsdPtr->oldFormatList; tsdPtr->oldFormatList = tsdPtr->oldFormatList->nextPtr; - ckfree((char *) freePtr->name); ckfree((char *) freePtr); } while (tsdPtr->formatList != NULL) { freePtr = tsdPtr->formatList; tsdPtr->formatList = tsdPtr->formatList->nextPtr; - ckfree((char *) freePtr->name); ckfree((char *) freePtr); } } @@ -508,8 +506,7 @@ Tk_CreateOldPhotoImageFormat( Tk_PhotoImageFormat *formatPtr) /* Structure describing the format. All of the * fields except "nextPtr" must be filled in - * by caller. Must not have been passed to - * Tk_CreatePhotoImageFormat previously. */ + * by caller. */ { Tk_PhotoImageFormat *copyPtr; ThreadSpecificData *tsdPtr = (ThreadSpecificData *) @@ -521,8 +518,6 @@ Tk_CreateOldPhotoImageFormat( } copyPtr = (Tk_PhotoImageFormat *) ckalloc(sizeof(Tk_PhotoImageFormat)); *copyPtr = *formatPtr; - copyPtr->name = (char *) ckalloc((unsigned) (strlen(formatPtr->name) + 1)); - strcpy(copyPtr->name, formatPtr->name); copyPtr->nextPtr = tsdPtr->oldFormatList; tsdPtr->oldFormatList = copyPtr; } @@ -532,8 +527,7 @@ Tk_CreatePhotoImageFormat( Tk_PhotoImageFormat *formatPtr) /* Structure describing the format. All of the * fields except "nextPtr" must be filled in - * by caller. Must not have been passed to - * Tk_CreatePhotoImageFormat previously. */ + * by caller. */ { Tk_PhotoImageFormat *copyPtr; ThreadSpecificData *tsdPtr = (ThreadSpecificData *) @@ -545,8 +539,6 @@ Tk_CreatePhotoImageFormat( } copyPtr = (Tk_PhotoImageFormat *) ckalloc(sizeof(Tk_PhotoImageFormat)); *copyPtr = *formatPtr; - copyPtr->name = (char *) ckalloc((unsigned) (strlen(formatPtr->name) + 1)); - strcpy(copyPtr->name, formatPtr->name); if (isupper((unsigned char) *formatPtr->name)) { copyPtr->nextPtr = tsdPtr->oldFormatList; tsdPtr->oldFormatList = copyPtr; @@ -4279,7 +4271,7 @@ Tk_FindPhoto( Tk_ImageType *typePtr; clientData = Tk_GetImageMasterData(interp, imageName, &typePtr); - if (typePtr != &tkPhotoImageType) { + if ((typePtr == NULL) || (typePtr->name != tkPhotoImageType.name)) { return NULL; } return (Tk_PhotoHandle) clientData; |