Date: Tuesday, September 10, 2013 @ 05:10:02
  Author: eric
Revision: 194018

upgpkg: tk 8.6.0-3

Add patch to fix seg fault in xcircuit (close FS#36843)

Added:
  tk/trunk/tk-xcircuit.patch
Modified:
  tk/trunk/PKGBUILD

-------------------+
 PKGBUILD          |   13 +-
 tk-xcircuit.patch |  317 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 326 insertions(+), 4 deletions(-)

Modified: PKGBUILD
===================================================================
--- PKGBUILD    2013-09-10 00:31:09 UTC (rev 194017)
+++ PKGBUILD    2013-09-10 03:10:02 UTC (rev 194018)
@@ -3,15 +3,21 @@
 
 pkgname=tk
 pkgver=8.6.0
-pkgrel=2
+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)
-sha1sums=('c42e160285e2d26eae8c2a1e6c6f86db4fa7663b')
+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"
@@ -33,5 +39,4 @@
 
   # remove buildroot traces
   sed -i "s#${srcdir}#/usr/src#" "${pkgdir}/usr/lib/tkConfig.sh"
-
 }

Added: tk-xcircuit.patch
===================================================================
--- tk-xcircuit.patch                           (rev 0)
+++ tk-xcircuit.patch   2013-09-10 03:10:02 UTC (rev 194018)
@@ -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
+

Reply via email to