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/tkImage.c | |
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/tkImage.c')
-rw-r--r-- | generic/tkImage.c | 77 |
1 files changed, 64 insertions, 13 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; } /* |