[arch-commits] Commit in tk/repos (6 files)
Eric Bélanger
eric at nymeria.archlinux.org
Tue Sep 10 03:10:45 UTC 2013
Date: Tuesday, September 10, 2013 @ 05:10:44
Author: eric
Revision: 194019
archrelease: copy trunk to extra-i686, extra-x86_64
Added:
tk/repos/extra-i686/PKGBUILD
(from rev 194018, tk/trunk/PKGBUILD)
tk/repos/extra-i686/tk-xcircuit.patch
(from rev 194018, tk/trunk/tk-xcircuit.patch)
tk/repos/extra-x86_64/PKGBUILD
(from rev 194018, tk/trunk/PKGBUILD)
tk/repos/extra-x86_64/tk-xcircuit.patch
(from rev 194018, tk/trunk/tk-xcircuit.patch)
Deleted:
tk/repos/extra-i686/PKGBUILD
tk/repos/extra-x86_64/PKGBUILD
--------------------------------+
/PKGBUILD | 84 ++++++++++
extra-i686/PKGBUILD | 37 ----
extra-i686/tk-xcircuit.patch | 317 +++++++++++++++++++++++++++++++++++++++
extra-x86_64/PKGBUILD | 37 ----
extra-x86_64/tk-xcircuit.patch | 317 +++++++++++++++++++++++++++++++++++++++
5 files changed, 718 insertions(+), 74 deletions(-)
Deleted: extra-i686/PKGBUILD
===================================================================
--- extra-i686/PKGBUILD 2013-09-10 03:10:02 UTC (rev 194018)
+++ extra-i686/PKGBUILD 2013-09-10 03:10:44 UTC (rev 194019)
@@ -1,37 +0,0 @@
-# $Id$
-# Maintainer: Eric Bélanger <eric at archlinux.org>
-
-pkgname=tk
-pkgver=8.6.0
-pkgrel=2
-pkgdesc="A windowing toolkit for use with tcl"
-arch=('i686' 'x86_64')
-url="http://tcl.sourceforge.net/"
-license=('custom')
-depends=("tcl=${pkgver}" 'libxss' 'libxft')
-source=(http://downloads.sourceforge.net/sourceforge/tcl/tk${pkgver}-src.tar.gz)
-sha1sums=('c42e160285e2d26eae8c2a1e6c6f86db4fa7663b')
-
-build() {
- cd tk${pkgver}/unix
- [[ $CARCH == "x86_64" ]] && BIT="--enable-64bit"
- ./configure --prefix=/usr --mandir=/usr/share/man --enable-threads --disable-rpath $BIT
- make
-}
-
-#check() {
-# cd tk${pkgver}/unix
-# make test
-#}
-
-package() {
- cd tk${pkgver}/unix
- make INSTALL_ROOT="${pkgdir}" install install-private-headers
- ln -sf wish8.6 "${pkgdir}/usr/bin/wish"
- ln -sf libtk${pkgver%.*}.so "${pkgdir}/usr/lib/libtk.so"
- install -Dm644 license.terms "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE"
-
- # remove buildroot traces
- sed -i "s#${srcdir}#/usr/src#" "${pkgdir}/usr/lib/tkConfig.sh"
-
-}
Copied: tk/repos/extra-i686/PKGBUILD (from rev 194018, tk/trunk/PKGBUILD)
===================================================================
--- extra-i686/PKGBUILD (rev 0)
+++ extra-i686/PKGBUILD 2013-09-10 03:10:44 UTC (rev 194019)
@@ -0,0 +1,42 @@
+# $Id$
+# Maintainer: Eric Bélanger <eric at archlinux.org>
+
+pkgname=tk
+pkgver=8.6.0
+pkgrel=3
+pkgdesc="A windowing toolkit for use with tcl"
+arch=('i686' 'x86_64')
+url="http://tcl.sourceforge.net/"
+license=('custom')
+depends=("tcl=${pkgver}" 'libxss' 'libxft')
+source=(http://downloads.sourceforge.net/sourceforge/tcl/tk${pkgver}-src.tar.gz tk-xcircuit.patch)
+sha1sums=('c42e160285e2d26eae8c2a1e6c6f86db4fa7663b'
+ 'e0e75044d4e33533b0114d3c142b40b7280c364f')
+
+prepare() {
+ cd tk${pkgver}
+ patch -p0 -i "${srcdir}/tk-xcircuit.patch"
+}
+
+build() {
+ cd tk${pkgver}/unix
+ [[ $CARCH == "x86_64" ]] && BIT="--enable-64bit"
+ ./configure --prefix=/usr --mandir=/usr/share/man --enable-threads --disable-rpath $BIT
+ make
+}
+
+#check() {
+# cd tk${pkgver}/unix
+# make test
+#}
+
+package() {
+ cd tk${pkgver}/unix
+ make INSTALL_ROOT="${pkgdir}" install install-private-headers
+ ln -sf wish8.6 "${pkgdir}/usr/bin/wish"
+ ln -sf libtk${pkgver%.*}.so "${pkgdir}/usr/lib/libtk.so"
+ install -Dm644 license.terms "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE"
+
+ # remove buildroot traces
+ sed -i "s#${srcdir}#/usr/src#" "${pkgdir}/usr/lib/tkConfig.sh"
+}
Copied: tk/repos/extra-i686/tk-xcircuit.patch (from rev 194018, tk/trunk/tk-xcircuit.patch)
===================================================================
--- extra-i686/tk-xcircuit.patch (rev 0)
+++ extra-i686/tk-xcircuit.patch 2013-09-10 03:10:44 UTC (rev 194019)
@@ -0,0 +1,317 @@
+Index: generic/tkConfig.c
+==================================================================
+--- generic/tkConfig.c
++++ generic/tkConfig.c
+@@ -29,11 +29,16 @@
+ /*
+ * The following definition is an AssocData key used to keep track of all of
+ * the option tables that have been created for an interpreter.
+ */
+
+-#define OPTION_HASH_KEY "TkOptionTable"
++typedef struct ThreadSpecificData {
++ int initialized; /* 0 means table below needs initializing. */
++ Tcl_HashTable hashTable;
++} ThreadSpecificData;
++static Tcl_ThreadDataKey dataKey;
++
+
+ /*
+ * The following two structures are used along with Tk_OptionSpec structures
+ * to manage configuration options. Tk_OptionSpec is static templates that are
+ * compiled into the code of a widget or other object manager. However, to
+@@ -98,12 +103,10 @@
+ * templates, this points to the table
+ * corresponding to the next template in the
+ * chain. */
+ int numOptions; /* The number of items in the options array
+ * below. */
+- int refCount2; /* Reference counter for controlling the freeing
+- * of the memory occupied by this OptionTable */
+ Option options[1]; /* Information about the individual options in
+ * the table. This must be the last field in
+ * the structure: the actual size of the array
+ * will be numOptions, not 1. */
+ } OptionTable;
+@@ -113,12 +116,10 @@
+ */
+
+ static int DoObjConfig(Tcl_Interp *interp, char *recordPtr,
+ Option *optionPtr, Tcl_Obj *valuePtr,
+ Tk_Window tkwin, Tk_SavedOption *savePtr);
+-static void DestroyOptionHashTable(ClientData clientData,
+- Tcl_Interp *interp);
+ static void FreeResources(Option *optionPtr, Tcl_Obj *objPtr,
+ char *internalPtr, Tk_Window tkwin);
+ static Tcl_Obj * GetConfigList(char *recordPtr,
+ Option *optionPtr, Tk_Window tkwin);
+ static Tcl_Obj * GetObjectForOption(char *recordPtr,
+@@ -168,42 +169,38 @@
+ * in which this table will be used. */
+ const Tk_OptionSpec *templatePtr)
+ /* Static information about the configuration
+ * options. */
+ {
+- Tcl_HashTable *hashTablePtr;
+ Tcl_HashEntry *hashEntryPtr;
+ int newEntry;
+ OptionTable *tablePtr;
+ const Tk_OptionSpec *specPtr, *specPtr2;
+ Option *optionPtr;
+ int numOptions, i;
++ ThreadSpecificData *tsdPtr =
++ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+
+ /*
+- * We use an AssocData value in the interpreter to keep a hash table of
+- * all the option tables we've created for this application. This is used
+- * for two purposes. First, it allows us to share the tables (e.g. in
+- * several chains) and second, we use the deletion callback for the
+- * AssocData to delete all the option tables when the interpreter is
+- * deleted. The code below finds the hash table or creates a new one if it
++ * We use an TSD in the thread to keep a hash table of
++ * all the option tables we've created for this application. This is
++ * used for allowing us to share the tables (e.g. in several chains).
++ * The code below finds the hash table or creates a new one if it
+ * doesn't already exist.
+ */
+
+- hashTablePtr = Tcl_GetAssocData(interp, OPTION_HASH_KEY, NULL);
+- if (hashTablePtr == NULL) {
+- hashTablePtr = ckalloc(sizeof(Tcl_HashTable));
+- Tcl_InitHashTable(hashTablePtr, TCL_ONE_WORD_KEYS);
+- Tcl_SetAssocData(interp, OPTION_HASH_KEY, DestroyOptionHashTable,
+- hashTablePtr);
++ if (!tsdPtr->initialized) {
++ Tcl_InitHashTable(&tsdPtr->hashTable, TCL_ONE_WORD_KEYS);
++ tsdPtr->initialized = 1;
+ }
+
+ /*
+ * See if a table has already been created for this template. If so, just
+ * reuse the existing table.
+ */
+
+- hashEntryPtr = Tcl_CreateHashEntry(hashTablePtr, (char *) templatePtr,
++ hashEntryPtr = Tcl_CreateHashEntry(&tsdPtr->hashTable, (char *) templatePtr,
+ &newEntry);
+ if (!newEntry) {
+ tablePtr = Tcl_GetHashValue(hashEntryPtr);
+ tablePtr->refCount++;
+ return (Tk_OptionTable) tablePtr;
+@@ -218,11 +215,10 @@
+ for (specPtr = templatePtr; specPtr->type != TK_OPTION_END; specPtr++) {
+ numOptions++;
+ }
+ tablePtr = ckalloc(sizeof(OptionTable) + (numOptions * sizeof(Option)));
+ tablePtr->refCount = 1;
+- tablePtr->refCount2 = 1;
+ tablePtr->hashEntryPtr = hashEntryPtr;
+ tablePtr->nextPtr = NULL;
+ tablePtr->numOptions = numOptions;
+
+ /*
+@@ -332,13 +328,20 @@
+ Tk_OptionTable optionTable) /* The option table to delete. */
+ {
+ OptionTable *tablePtr = (OptionTable *) optionTable;
+ Option *optionPtr;
+ int count;
++ ThreadSpecificData *tsdPtr =
++ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+
+- tablePtr->refCount--;
+- if (tablePtr->refCount > 0) {
++ if (tablePtr->refCount > 1) {
++ tablePtr->refCount--;
++ return;
++ }
++
++ if (!tsdPtr->initialized || !Tcl_FindHashEntry(&tsdPtr->hashTable,
++ tablePtr->hashEntryPtr)) {
+ return;
+ }
+
+ if (tablePtr->nextPtr != NULL) {
+ Tk_DeleteOptionTable((Tk_OptionTable) tablePtr->nextPtr);
+@@ -354,66 +357,11 @@
+ && (optionPtr->extra.monoColorPtr != NULL)) {
+ Tcl_DecrRefCount(optionPtr->extra.monoColorPtr);
+ }
+ }
+ Tcl_DeleteHashEntry(tablePtr->hashEntryPtr);
+- tablePtr->refCount2--;
+- if (tablePtr->refCount2 <= 0) {
+- ckfree(tablePtr);
+- }
+-}
+-
+-/*
+- *----------------------------------------------------------------------
+- *
+- * DestroyOptionHashTable --
+- *
+- * This function is the deletion callback associated with the AssocData
+- * entry created by Tk_CreateOptionTable. It is invoked when an
+- * interpreter is deleted, and deletes all of the option tables
+- * associated with that interpreter.
+- *
+- * Results:
+- * None.
+- *
+- * Side effects:
+- * The option hash table is destroyed along with all of the OptionTable
+- * structures that it refers to.
+- *
+- *----------------------------------------------------------------------
+- */
+-
+-static void
+-DestroyOptionHashTable(
+- ClientData clientData, /* The hash table we are destroying */
+- Tcl_Interp *interp) /* The interpreter we are destroying */
+-{
+- Tcl_HashTable *hashTablePtr = clientData;
+- Tcl_HashSearch search;
+- Tcl_HashEntry *hashEntryPtr;
+-
+- for (hashEntryPtr = Tcl_FirstHashEntry(hashTablePtr, &search);
+- hashEntryPtr != NULL;
+- hashEntryPtr = Tcl_NextHashEntry(&search)) {
+- OptionTable *tablePtr = Tcl_GetHashValue(hashEntryPtr);
+-
+- /*
+- * The following statements do two tricky things:
+- * 1. They ensure that the option table is deleted, even if there are
+- * outstanding references to it.
+- * 2. They ensure that Tk_DeleteOptionTable doesn't delete other
+- * tables chained from this one; we'll do it when we come across
+- * the hash table entry for the chained table (in fact, the chained
+- * table may already have been deleted).
+- */
+-
+- tablePtr->refCount = 1;
+- tablePtr->nextPtr = NULL;
+- Tk_DeleteOptionTable((Tk_OptionTable) tablePtr);
+- }
+- Tcl_DeleteHashTable(hashTablePtr);
+- ckfree(hashTablePtr);
++ ckfree(tablePtr);
+ }
+
+ /*
+ *--------------------------------------------------------------
+ *
+@@ -1149,11 +1097,11 @@
+ objPtr->typePtr->freeIntRepProc(objPtr);
+ }
+ objPtr->internalRep.twoPtrValue.ptr1 = (void *) tablePtr;
+ objPtr->internalRep.twoPtrValue.ptr2 = (void *) bestPtr;
+ objPtr->typePtr = &optionObjType;
+- tablePtr->refCount2++;
++ tablePtr->refCount++;
+ return bestPtr;
+
+ error:
+ if (interp != NULL) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+@@ -1222,16 +1170,13 @@
+
+ static void
+ FreeOptionInternalRep(
+ register Tcl_Obj *objPtr) /* Object whose internal rep to free. */
+ {
+- register OptionTable *tablePtr = (OptionTable *) objPtr->internalRep.twoPtrValue.ptr1;
++ register Tk_OptionTable tablePtr = (Tk_OptionTable) objPtr->internalRep.twoPtrValue.ptr1;
+
+- tablePtr->refCount2--;
+- if (tablePtr->refCount2 <= 0) {
+- ckfree(tablePtr);
+- }
++ Tk_DeleteOptionTable(tablePtr);
+ objPtr->typePtr = NULL;
+ objPtr->internalRep.twoPtrValue.ptr1 = NULL;
+ objPtr->internalRep.twoPtrValue.ptr2 = NULL;
+ }
+
+@@ -2111,27 +2056,27 @@
+ Tk_OptionTable table) /* Table about which information is to be
+ * returned. May not necessarily exist in the
+ * interpreter anymore. */
+ {
+ OptionTable *tablePtr = (OptionTable *) table;
+- Tcl_HashTable *hashTablePtr;
+ Tcl_HashEntry *hashEntryPtr;
+ Tcl_HashSearch search;
+ Tcl_Obj *objPtr;
++ ThreadSpecificData *tsdPtr =
++ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+
+ objPtr = Tcl_NewObj();
+- hashTablePtr = Tcl_GetAssocData(interp, OPTION_HASH_KEY, NULL);
+- if (hashTablePtr == NULL) {
++ if (!tablePtr || !tsdPtr->initialized) {
+ return objPtr;
+ }
+
+ /*
+ * Scan all the tables for this interpreter to make sure that the one we
+ * want still is valid.
+ */
+
+- for (hashEntryPtr = Tcl_FirstHashEntry(hashTablePtr, &search);
++ for (hashEntryPtr = Tcl_FirstHashEntry(&tsdPtr->hashTable, &search);
+ hashEntryPtr != NULL;
+ hashEntryPtr = Tcl_NextHashEntry(&search)) {
+ if (tablePtr == (OptionTable *) Tcl_GetHashValue(hashEntryPtr)) {
+ for ( ; tablePtr != NULL; tablePtr = tablePtr->nextPtr) {
+ Tcl_ListObjAppendElement(NULL, objPtr,
+
+Index: generic/tkTest.c
+==================================================================
+--- generic/tkTest.c
++++ generic/tkTest.c
+@@ -801,10 +801,11 @@
+ sizeof(char *), "table", 0, &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (tables[index] != NULL) {
+ Tk_DeleteOptionTable(tables[index]);
++ tables[index] = NULL;
+ }
+ break;
+
+ case INFO:
+ if (objc != 3) {
+
+Index: tests/config.test
+==================================================================
+--- tests/config.test
++++ tests/config.test
+@@ -96,11 +96,11 @@
+ testobjconfig chain2 .b
+ testobjconfig chain1 .a
+ testobjconfig info chain2
+ } -cleanup {
+ killTables
+-} -result {1 4 -three 2 2 -one}
++} -result {2 4 -three 2 2 -one}
+ test config-1.8 {Tk_CreateOptionTable - chained tables} -constraints {
+ testobjconfig
+ } -body {
+ testobjconfig chain1 .a
+ testobjconfig chain2 .b
+@@ -132,11 +132,11 @@
+ lappend x [testobjconfig info chain2] [testobjconfig info chain1]
+ testobjconfig delete chain2
+ lappend x [testobjconfig info chain2] [testobjconfig info chain1]
+ } -cleanup {
+ killTables
+-} -result {{1 4 -three 2 2 -one} {2 2 -one} {} {1 2 -one}}
++} -result {{} {2 2 -one} {} {2 2 -one}}
+
+ # No tests for DestroyOptionHashTable; couldn't figure out how to test.
+
+ test config-3.1 {Tk_InitOptions - priority of chained tables} -constraints {
+ testobjconfig
+
Deleted: extra-x86_64/PKGBUILD
===================================================================
--- extra-x86_64/PKGBUILD 2013-09-10 03:10:02 UTC (rev 194018)
+++ extra-x86_64/PKGBUILD 2013-09-10 03:10:44 UTC (rev 194019)
@@ -1,37 +0,0 @@
-# $Id$
-# Maintainer: Eric Bélanger <eric at archlinux.org>
-
-pkgname=tk
-pkgver=8.6.0
-pkgrel=2
-pkgdesc="A windowing toolkit for use with tcl"
-arch=('i686' 'x86_64')
-url="http://tcl.sourceforge.net/"
-license=('custom')
-depends=("tcl=${pkgver}" 'libxss' 'libxft')
-source=(http://downloads.sourceforge.net/sourceforge/tcl/tk${pkgver}-src.tar.gz)
-sha1sums=('c42e160285e2d26eae8c2a1e6c6f86db4fa7663b')
-
-build() {
- cd tk${pkgver}/unix
- [[ $CARCH == "x86_64" ]] && BIT="--enable-64bit"
- ./configure --prefix=/usr --mandir=/usr/share/man --enable-threads --disable-rpath $BIT
- make
-}
-
-#check() {
-# cd tk${pkgver}/unix
-# make test
-#}
-
-package() {
- cd tk${pkgver}/unix
- make INSTALL_ROOT="${pkgdir}" install install-private-headers
- ln -sf wish8.6 "${pkgdir}/usr/bin/wish"
- ln -sf libtk${pkgver%.*}.so "${pkgdir}/usr/lib/libtk.so"
- install -Dm644 license.terms "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE"
-
- # remove buildroot traces
- sed -i "s#${srcdir}#/usr/src#" "${pkgdir}/usr/lib/tkConfig.sh"
-
-}
Copied: tk/repos/extra-x86_64/PKGBUILD (from rev 194018, tk/trunk/PKGBUILD)
===================================================================
--- extra-x86_64/PKGBUILD (rev 0)
+++ extra-x86_64/PKGBUILD 2013-09-10 03:10:44 UTC (rev 194019)
@@ -0,0 +1,42 @@
+# $Id$
+# Maintainer: Eric Bélanger <eric at archlinux.org>
+
+pkgname=tk
+pkgver=8.6.0
+pkgrel=3
+pkgdesc="A windowing toolkit for use with tcl"
+arch=('i686' 'x86_64')
+url="http://tcl.sourceforge.net/"
+license=('custom')
+depends=("tcl=${pkgver}" 'libxss' 'libxft')
+source=(http://downloads.sourceforge.net/sourceforge/tcl/tk${pkgver}-src.tar.gz tk-xcircuit.patch)
+sha1sums=('c42e160285e2d26eae8c2a1e6c6f86db4fa7663b'
+ 'e0e75044d4e33533b0114d3c142b40b7280c364f')
+
+prepare() {
+ cd tk${pkgver}
+ patch -p0 -i "${srcdir}/tk-xcircuit.patch"
+}
+
+build() {
+ cd tk${pkgver}/unix
+ [[ $CARCH == "x86_64" ]] && BIT="--enable-64bit"
+ ./configure --prefix=/usr --mandir=/usr/share/man --enable-threads --disable-rpath $BIT
+ make
+}
+
+#check() {
+# cd tk${pkgver}/unix
+# make test
+#}
+
+package() {
+ cd tk${pkgver}/unix
+ make INSTALL_ROOT="${pkgdir}" install install-private-headers
+ ln -sf wish8.6 "${pkgdir}/usr/bin/wish"
+ ln -sf libtk${pkgver%.*}.so "${pkgdir}/usr/lib/libtk.so"
+ install -Dm644 license.terms "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE"
+
+ # remove buildroot traces
+ sed -i "s#${srcdir}#/usr/src#" "${pkgdir}/usr/lib/tkConfig.sh"
+}
Copied: tk/repos/extra-x86_64/tk-xcircuit.patch (from rev 194018, tk/trunk/tk-xcircuit.patch)
===================================================================
--- extra-x86_64/tk-xcircuit.patch (rev 0)
+++ extra-x86_64/tk-xcircuit.patch 2013-09-10 03:10:44 UTC (rev 194019)
@@ -0,0 +1,317 @@
+Index: generic/tkConfig.c
+==================================================================
+--- generic/tkConfig.c
++++ generic/tkConfig.c
+@@ -29,11 +29,16 @@
+ /*
+ * The following definition is an AssocData key used to keep track of all of
+ * the option tables that have been created for an interpreter.
+ */
+
+-#define OPTION_HASH_KEY "TkOptionTable"
++typedef struct ThreadSpecificData {
++ int initialized; /* 0 means table below needs initializing. */
++ Tcl_HashTable hashTable;
++} ThreadSpecificData;
++static Tcl_ThreadDataKey dataKey;
++
+
+ /*
+ * The following two structures are used along with Tk_OptionSpec structures
+ * to manage configuration options. Tk_OptionSpec is static templates that are
+ * compiled into the code of a widget or other object manager. However, to
+@@ -98,12 +103,10 @@
+ * templates, this points to the table
+ * corresponding to the next template in the
+ * chain. */
+ int numOptions; /* The number of items in the options array
+ * below. */
+- int refCount2; /* Reference counter for controlling the freeing
+- * of the memory occupied by this OptionTable */
+ Option options[1]; /* Information about the individual options in
+ * the table. This must be the last field in
+ * the structure: the actual size of the array
+ * will be numOptions, not 1. */
+ } OptionTable;
+@@ -113,12 +116,10 @@
+ */
+
+ static int DoObjConfig(Tcl_Interp *interp, char *recordPtr,
+ Option *optionPtr, Tcl_Obj *valuePtr,
+ Tk_Window tkwin, Tk_SavedOption *savePtr);
+-static void DestroyOptionHashTable(ClientData clientData,
+- Tcl_Interp *interp);
+ static void FreeResources(Option *optionPtr, Tcl_Obj *objPtr,
+ char *internalPtr, Tk_Window tkwin);
+ static Tcl_Obj * GetConfigList(char *recordPtr,
+ Option *optionPtr, Tk_Window tkwin);
+ static Tcl_Obj * GetObjectForOption(char *recordPtr,
+@@ -168,42 +169,38 @@
+ * in which this table will be used. */
+ const Tk_OptionSpec *templatePtr)
+ /* Static information about the configuration
+ * options. */
+ {
+- Tcl_HashTable *hashTablePtr;
+ Tcl_HashEntry *hashEntryPtr;
+ int newEntry;
+ OptionTable *tablePtr;
+ const Tk_OptionSpec *specPtr, *specPtr2;
+ Option *optionPtr;
+ int numOptions, i;
++ ThreadSpecificData *tsdPtr =
++ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+
+ /*
+- * We use an AssocData value in the interpreter to keep a hash table of
+- * all the option tables we've created for this application. This is used
+- * for two purposes. First, it allows us to share the tables (e.g. in
+- * several chains) and second, we use the deletion callback for the
+- * AssocData to delete all the option tables when the interpreter is
+- * deleted. The code below finds the hash table or creates a new one if it
++ * We use an TSD in the thread to keep a hash table of
++ * all the option tables we've created for this application. This is
++ * used for allowing us to share the tables (e.g. in several chains).
++ * The code below finds the hash table or creates a new one if it
+ * doesn't already exist.
+ */
+
+- hashTablePtr = Tcl_GetAssocData(interp, OPTION_HASH_KEY, NULL);
+- if (hashTablePtr == NULL) {
+- hashTablePtr = ckalloc(sizeof(Tcl_HashTable));
+- Tcl_InitHashTable(hashTablePtr, TCL_ONE_WORD_KEYS);
+- Tcl_SetAssocData(interp, OPTION_HASH_KEY, DestroyOptionHashTable,
+- hashTablePtr);
++ if (!tsdPtr->initialized) {
++ Tcl_InitHashTable(&tsdPtr->hashTable, TCL_ONE_WORD_KEYS);
++ tsdPtr->initialized = 1;
+ }
+
+ /*
+ * See if a table has already been created for this template. If so, just
+ * reuse the existing table.
+ */
+
+- hashEntryPtr = Tcl_CreateHashEntry(hashTablePtr, (char *) templatePtr,
++ hashEntryPtr = Tcl_CreateHashEntry(&tsdPtr->hashTable, (char *) templatePtr,
+ &newEntry);
+ if (!newEntry) {
+ tablePtr = Tcl_GetHashValue(hashEntryPtr);
+ tablePtr->refCount++;
+ return (Tk_OptionTable) tablePtr;
+@@ -218,11 +215,10 @@
+ for (specPtr = templatePtr; specPtr->type != TK_OPTION_END; specPtr++) {
+ numOptions++;
+ }
+ tablePtr = ckalloc(sizeof(OptionTable) + (numOptions * sizeof(Option)));
+ tablePtr->refCount = 1;
+- tablePtr->refCount2 = 1;
+ tablePtr->hashEntryPtr = hashEntryPtr;
+ tablePtr->nextPtr = NULL;
+ tablePtr->numOptions = numOptions;
+
+ /*
+@@ -332,13 +328,20 @@
+ Tk_OptionTable optionTable) /* The option table to delete. */
+ {
+ OptionTable *tablePtr = (OptionTable *) optionTable;
+ Option *optionPtr;
+ int count;
++ ThreadSpecificData *tsdPtr =
++ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+
+- tablePtr->refCount--;
+- if (tablePtr->refCount > 0) {
++ if (tablePtr->refCount > 1) {
++ tablePtr->refCount--;
++ return;
++ }
++
++ if (!tsdPtr->initialized || !Tcl_FindHashEntry(&tsdPtr->hashTable,
++ tablePtr->hashEntryPtr)) {
+ return;
+ }
+
+ if (tablePtr->nextPtr != NULL) {
+ Tk_DeleteOptionTable((Tk_OptionTable) tablePtr->nextPtr);
+@@ -354,66 +357,11 @@
+ && (optionPtr->extra.monoColorPtr != NULL)) {
+ Tcl_DecrRefCount(optionPtr->extra.monoColorPtr);
+ }
+ }
+ Tcl_DeleteHashEntry(tablePtr->hashEntryPtr);
+- tablePtr->refCount2--;
+- if (tablePtr->refCount2 <= 0) {
+- ckfree(tablePtr);
+- }
+-}
+-
+-/*
+- *----------------------------------------------------------------------
+- *
+- * DestroyOptionHashTable --
+- *
+- * This function is the deletion callback associated with the AssocData
+- * entry created by Tk_CreateOptionTable. It is invoked when an
+- * interpreter is deleted, and deletes all of the option tables
+- * associated with that interpreter.
+- *
+- * Results:
+- * None.
+- *
+- * Side effects:
+- * The option hash table is destroyed along with all of the OptionTable
+- * structures that it refers to.
+- *
+- *----------------------------------------------------------------------
+- */
+-
+-static void
+-DestroyOptionHashTable(
+- ClientData clientData, /* The hash table we are destroying */
+- Tcl_Interp *interp) /* The interpreter we are destroying */
+-{
+- Tcl_HashTable *hashTablePtr = clientData;
+- Tcl_HashSearch search;
+- Tcl_HashEntry *hashEntryPtr;
+-
+- for (hashEntryPtr = Tcl_FirstHashEntry(hashTablePtr, &search);
+- hashEntryPtr != NULL;
+- hashEntryPtr = Tcl_NextHashEntry(&search)) {
+- OptionTable *tablePtr = Tcl_GetHashValue(hashEntryPtr);
+-
+- /*
+- * The following statements do two tricky things:
+- * 1. They ensure that the option table is deleted, even if there are
+- * outstanding references to it.
+- * 2. They ensure that Tk_DeleteOptionTable doesn't delete other
+- * tables chained from this one; we'll do it when we come across
+- * the hash table entry for the chained table (in fact, the chained
+- * table may already have been deleted).
+- */
+-
+- tablePtr->refCount = 1;
+- tablePtr->nextPtr = NULL;
+- Tk_DeleteOptionTable((Tk_OptionTable) tablePtr);
+- }
+- Tcl_DeleteHashTable(hashTablePtr);
+- ckfree(hashTablePtr);
++ ckfree(tablePtr);
+ }
+
+ /*
+ *--------------------------------------------------------------
+ *
+@@ -1149,11 +1097,11 @@
+ objPtr->typePtr->freeIntRepProc(objPtr);
+ }
+ objPtr->internalRep.twoPtrValue.ptr1 = (void *) tablePtr;
+ objPtr->internalRep.twoPtrValue.ptr2 = (void *) bestPtr;
+ objPtr->typePtr = &optionObjType;
+- tablePtr->refCount2++;
++ tablePtr->refCount++;
+ return bestPtr;
+
+ error:
+ if (interp != NULL) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+@@ -1222,16 +1170,13 @@
+
+ static void
+ FreeOptionInternalRep(
+ register Tcl_Obj *objPtr) /* Object whose internal rep to free. */
+ {
+- register OptionTable *tablePtr = (OptionTable *) objPtr->internalRep.twoPtrValue.ptr1;
++ register Tk_OptionTable tablePtr = (Tk_OptionTable) objPtr->internalRep.twoPtrValue.ptr1;
+
+- tablePtr->refCount2--;
+- if (tablePtr->refCount2 <= 0) {
+- ckfree(tablePtr);
+- }
++ Tk_DeleteOptionTable(tablePtr);
+ objPtr->typePtr = NULL;
+ objPtr->internalRep.twoPtrValue.ptr1 = NULL;
+ objPtr->internalRep.twoPtrValue.ptr2 = NULL;
+ }
+
+@@ -2111,27 +2056,27 @@
+ Tk_OptionTable table) /* Table about which information is to be
+ * returned. May not necessarily exist in the
+ * interpreter anymore. */
+ {
+ OptionTable *tablePtr = (OptionTable *) table;
+- Tcl_HashTable *hashTablePtr;
+ Tcl_HashEntry *hashEntryPtr;
+ Tcl_HashSearch search;
+ Tcl_Obj *objPtr;
++ ThreadSpecificData *tsdPtr =
++ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+
+ objPtr = Tcl_NewObj();
+- hashTablePtr = Tcl_GetAssocData(interp, OPTION_HASH_KEY, NULL);
+- if (hashTablePtr == NULL) {
++ if (!tablePtr || !tsdPtr->initialized) {
+ return objPtr;
+ }
+
+ /*
+ * Scan all the tables for this interpreter to make sure that the one we
+ * want still is valid.
+ */
+
+- for (hashEntryPtr = Tcl_FirstHashEntry(hashTablePtr, &search);
++ for (hashEntryPtr = Tcl_FirstHashEntry(&tsdPtr->hashTable, &search);
+ hashEntryPtr != NULL;
+ hashEntryPtr = Tcl_NextHashEntry(&search)) {
+ if (tablePtr == (OptionTable *) Tcl_GetHashValue(hashEntryPtr)) {
+ for ( ; tablePtr != NULL; tablePtr = tablePtr->nextPtr) {
+ Tcl_ListObjAppendElement(NULL, objPtr,
+
+Index: generic/tkTest.c
+==================================================================
+--- generic/tkTest.c
++++ generic/tkTest.c
+@@ -801,10 +801,11 @@
+ sizeof(char *), "table", 0, &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (tables[index] != NULL) {
+ Tk_DeleteOptionTable(tables[index]);
++ tables[index] = NULL;
+ }
+ break;
+
+ case INFO:
+ if (objc != 3) {
+
+Index: tests/config.test
+==================================================================
+--- tests/config.test
++++ tests/config.test
+@@ -96,11 +96,11 @@
+ testobjconfig chain2 .b
+ testobjconfig chain1 .a
+ testobjconfig info chain2
+ } -cleanup {
+ killTables
+-} -result {1 4 -three 2 2 -one}
++} -result {2 4 -three 2 2 -one}
+ test config-1.8 {Tk_CreateOptionTable - chained tables} -constraints {
+ testobjconfig
+ } -body {
+ testobjconfig chain1 .a
+ testobjconfig chain2 .b
+@@ -132,11 +132,11 @@
+ lappend x [testobjconfig info chain2] [testobjconfig info chain1]
+ testobjconfig delete chain2
+ lappend x [testobjconfig info chain2] [testobjconfig info chain1]
+ } -cleanup {
+ killTables
+-} -result {{1 4 -three 2 2 -one} {2 2 -one} {} {1 2 -one}}
++} -result {{} {2 2 -one} {} {2 2 -one}}
+
+ # No tests for DestroyOptionHashTable; couldn't figure out how to test.
+
+ test config-3.1 {Tk_InitOptions - priority of chained tables} -constraints {
+ testobjconfig
+
More information about the arch-commits
mailing list