Index: trunk/psLib/src/imageops/psImageConvolve.c
===================================================================
--- trunk/psLib/src/imageops/psImageConvolve.c	(revision 19056)
+++ trunk/psLib/src/imageops/psImageConvolve.c	(revision 19057)
@@ -7,6 +7,6 @@
 /// @author Eugene Magnier, IfA
 ///
-/// @version $Revision: 1.73 $ $Name: not supported by cvs2svn $
-/// @date $Date: 2008-08-12 03:08:41 $
+/// @version $Revision: 1.74 $ $Name: not supported by cvs2svn $
+/// @date $Date: 2008-08-14 03:22:13 $
 ///
 /// Copyright 2004-2007 Institute for Astronomy, University of Hawaii
@@ -1071,5 +1071,5 @@
         }
     } else if (!set && threaded) {
-        psThreadTaskDelete("PSLIB_IMAGE_CONVOLVE_MASK");
+        psThreadTaskRemove("PSLIB_IMAGE_CONVOLVE_MASK");
     }
 
Index: trunk/psLib/src/sys/psThread.c
===================================================================
--- trunk/psLib/src/sys/psThread.c	(revision 19056)
+++ trunk/psLib/src/sys/psThread.c	(revision 19057)
@@ -26,4 +26,5 @@
 static psArray *pool = NULL;            // array of defined threads
 static psHash *tasks = NULL;            // List of defined tasks
+static psArray *tsd = NULL;             // Thread-specific data
 
 
@@ -165,5 +166,5 @@
 }
 
-bool psThreadTaskDelete(const char *type)
+bool psThreadTaskRemove(const char *type)
 {
     PS_ASSERT_STRING_NON_EMPTY(type, false);
@@ -316,5 +317,69 @@
     tasks = NULL;
 
+    psFree(tsd);
+    tsd = NULL;
+
     return true;
 }
 
+
+#if 0
+// This doesn't work like I thought it would: pthread_self can return anything.
+bool psThreadDataAdd(const char *name, psPtr ptr)
+{
+    PS_ASSERT_STRING_NON_EMPTY(name, false);
+    PS_ASSERT_PTR_NON_NULL(ptr, false);
+
+    pthread_key_t *key = psAlloc(sizeof(pthread_key_t)); // Key for data
+    pthread_key_create(key, psFree);
+
+    if (!tsd) {
+        tsd = psArrayAlloc(numThreads);
+    }
+
+    psHashAdd(
+
+    pthread_t tid = pthread_self();     // Thread identifier
+    int numThreads = psThreadPoolSize();// Number of threads
+    psAssert(tid < numThreads, "Thread identifier (%d) exceeds number of threads (%d)", (int)tid, numThreads);
+
+    if (!tsd) {
+        tsd = psArrayAlloc(numThreads);
+    }
+
+    psHash *hash = tsd->data[tid];      // Thread-specific hash of data
+    return psHashAdd(hash, name, ptr);
+}
+
+void *psThreadDataLookup(const char *name)
+{
+    PS_ASSERT_STRING_NON_EMPTY(name, NULL);
+
+    if (!tsd) {
+        return NULL;
+    }
+
+    pthread_t tid = pthread_self();     // Thread identifier
+    int numThreads = psThreadPoolSize();// Number of threads
+    psAssert(tid < numThreads, "Thread identifier (%d) exceeds number of threads (%d)", (int)tid, numThreads);
+
+    psHash *hash = tsd->data[tid];      // Thread-specific hash of data
+    return psHashLookup(hash, name);
+}
+
+bool psThreadDataRemove(const char *name)
+{
+    PS_ASSERT_STRING_NON_EMPTY(name, false);
+
+    if (!tsd) {
+        return false;
+    }
+
+    pthread_t tid = pthread_self();     // Thread identifier
+    int numThreads = psThreadPoolSize();// Number of threads
+    psAssert(tid < numThreads, "Thread identifier (%d) exceeds number of threads (%d)", (int)tid, numThreads);
+
+    psHash *hash = tsd->data[tid];      // Thread-specific hash of data
+    return psHashRemove(hash, name);
+}
+#endif
Index: trunk/psLib/src/sys/psThread.h
===================================================================
--- trunk/psLib/src/sys/psThread.h	(revision 19056)
+++ trunk/psLib/src/sys/psThread.h	(revision 19057)
@@ -4,6 +4,6 @@
  *
  *  @author EAM, IFA
- *  @version $Revision: 1.4 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2008-08-12 03:28:37 $
+ *  @version $Revision: 1.5 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2008-08-14 03:22:13 $
  *
  *  Copyright 2004-2005 Insitute for Astronomy, University of Hawaii
@@ -12,4 +12,8 @@
 #ifndef PS_THREAD_H
 #define PS_THREAD_H
+
+#include <pthread.h>
+#include "psString.h"
+#include "psArray.h"
 
 /// @addtogroup SysUtils System Utilities
@@ -87,5 +91,5 @@
 
 /// Remove a task from the list
-bool psThreadTaskDelete(const char *type // Task type to remove
+bool psThreadTaskRemove(const char *type // Task type to remove
     );
 
@@ -111,4 +115,25 @@
 bool psThreadPoolFinalize(void);
 
+
+/// Add thread-specific data
+///
+/// The provided pointer is added to a thread-specific hash under the provided name.
+bool psThreadDataAdd(const char *name,  // Name of data
+                     psPtr ptr          // Data to add
+    );
+
+/// Lookup thread-specific data
+///
+/// The thread-specific hash is interrogated using the provided name.
+void *psThreadDataLookup(const char *name // Name of data
+    );
+
+/// Remove thread-specific data
+///
+/// The thread-specific hash has the data associated with the provided name deleted.
+bool psThreadDataRemove(const char *name // Name of data
+    );
+
+
 /// @}
 #endif /* PS_THREAD_H */
