summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--generic/tkImage.c77
-rw-r--r--generic/tkImgPhoto.c16
3 files changed, 76 insertions, 25 deletions
diff --git a/ChangeLog b/ChangeLog
index 7836bc5..5b25111 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2008-11-19 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tkImage.c Relax the constraint that every Tk_ImageType
+ * generic/tkImgPhoto.c can only be passed to this function once.
+ This allows tkImg to be loaded in multiple
+ interpreters in a thread-enabled build of Tk.
+ [Bug 2312027]
+
2008-11-15 Pat Thoyts <patthoyts@users.sourceforge.net>
* generic/tk.h: The tip 125 implementation permits the
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;