Index: trunk/psLib/src/imageops/psImageConvolve.c
===================================================================
--- trunk/psLib/src/imageops/psImageConvolve.c	(revision 33030)
+++ trunk/psLib/src/imageops/psImageConvolve.c	(revision 33089)
@@ -1039,5 +1039,5 @@
             }
         }
-        if (!psThreadPoolWait(true)) {
+        if (!psThreadPoolWait(true, true)) {
             psError(PS_ERR_UNKNOWN, false, "Error waiting for threads.");
             psFree(gaussNorm);
@@ -1390,5 +1390,5 @@
               }
               // wait here for the threaded jobs to finish (NOP if threading is not active)
-              if (!psThreadPoolWait(true)) {
+              if (!psThreadPoolWait(true, true)) {
                   psError(PS_ERR_UNKNOWN, false, "Unable to smooth image");
                   psFree(calculation);
@@ -1437,5 +1437,5 @@
 
               // wait here for the threaded jobs to finish (NOP if threading is not active)
-              if (!psThreadPoolWait(true)) {
+              if (!psThreadPoolWait(true, true)) {
                   psError(PS_ERR_UNKNOWN, false, "Unable to smooth image");
                   psFree(calculation);
@@ -1752,5 +1752,5 @@
             }
         }
-        if (!psThreadPoolWait(true)) {
+        if (!psThreadPoolWait(true, true)) {
             psError(PS_ERR_UNKNOWN, false, "Error waiting for threads.");
             psFree(conv);
@@ -1787,5 +1787,5 @@
             }
         }
-        if (!psThreadPoolWait(true)) {
+        if (!psThreadPoolWait(true, true)) {
             psError(PS_ERR_UNKNOWN, false, "Error waiting for threads.");
             psFree(conv);
Index: trunk/psLib/src/imageops/psImageCovariance.c
===================================================================
--- trunk/psLib/src/imageops/psImageCovariance.c	(revision 33030)
+++ trunk/psLib/src/imageops/psImageCovariance.c	(revision 33089)
@@ -193,5 +193,5 @@
     }
 
-    if (threaded && !psThreadPoolWait(true)) {
+    if (threaded && !psThreadPoolWait(true, true)) {
         psError(PS_ERR_UNKNOWN, false, "Error waiting for threads.");
         return false;
@@ -360,5 +360,5 @@
         }
     }
-    if (threaded && !psThreadPoolWait(true)) {
+    if (threaded && !psThreadPoolWait(true, true)) {
         psError(PS_ERR_UNKNOWN, false, "Error waiting for threads.");
         return false;
Index: trunk/psLib/src/sys/psThread.c
===================================================================
--- trunk/psLib/src/sys/psThread.c	(revision 33030)
+++ trunk/psLib/src/sys/psThread.c	(revision 33089)
@@ -179,4 +179,6 @@
     PS_ASSERT_THREAD_TASK_NON_NULL(task, false);
 
+    // fprintf(stderr, "adding task %s\n", task->type);
+
     if (!tasks) {
         tasks = psHashAlloc(TASK_BUCKETS);
@@ -189,4 +191,5 @@
 {
     PS_ASSERT_STRING_NON_EMPTY(type, false);
+    // fprintf(stderr, "removing task %s\n", type);
 
     return psHashRemove(tasks, type);
@@ -223,4 +226,5 @@
 
         psThreadTask *task = psHashLookup(tasks, job->type); // Task to execute job
+        // fprintf(stderr, "launching job %s\n", job->type);
 #ifdef HAVE_BACKTRACE
         if (!task && bt_buffer) {
@@ -246,5 +250,10 @@
                  "invalid number of arguments to %s (%ld supplied, expected %d)",
                  task->type, job->args->n, task->nArgs);
+        // fprintf(stderr, "    thread for %s %p launching on %p\n", job->type, task->function, self);
+
+        // Run the job's function
         bool status = task->function(job); // Status of executing task
+
+        // fprintf(stderr, "    thread for %s %p finished on %p with status %d\n", job->type, task->function, self, status);
 
         // Put the completed job on the 'done' queue
@@ -306,6 +315,7 @@
 
 // call this function after you have added jobs to the queue and
-bool psThreadPoolWait(bool harvest)
-{
+bool psThreadPoolWait(bool harvest, bool harvestOnFailure)
+{
+    // fprintf(stderr, "psThreadPoolWait called with harvest: %d\n", harvest);
     if (!pool || pool->n == 0) {
         // No threads initialised, so everything's done
@@ -326,4 +336,6 @@
 #endif
 
+    // accumulate the number of faulted jobs that we encounter
+    int numFaults = 0;
     while (1) {
         // check for an error
@@ -331,5 +343,5 @@
             psThread *thread = pool->data[i];
             if (thread->fault) {
-                return false;
+                numFaults++;
             }
         }
@@ -354,9 +366,9 @@
             // Nothing in the queue and nothing more to add
             // Ensure everything is harvested, if requested
-            if (harvest) {
+            if (harvest || (numFaults && harvestOnFailure)) {
                 psThreadJobHarvest();
             }
             psThreadUnlock();
-            return true;
+            return numFaults == 0;
         }
 
Index: trunk/psLib/src/sys/psThread.h
===================================================================
--- trunk/psLib/src/sys/psThread.h	(revision 33030)
+++ trunk/psLib/src/sys/psThread.h	(revision 33089)
@@ -116,7 +116,9 @@
 /// Wait for the thread pool to finish
 ///
-/// This function blocks (waits in usleep) until either an error is detected on one of the threads or until ll
-/// threads are idle and no jobs are left on the queue
-bool psThreadPoolWait(bool harvest      // Harvest the jobs from the queue?
+/// This function blocks (waits in usleep) until all  threads are idle and no jobs
+/// are left on the queue
+/// returns success if all jobs return success, otherwise returns false
+bool psThreadPoolWait(bool harvest,         // Harvest the jobs from the queue?
+                      bool harvestOnFailure // If harvest is false, harvest the jobs if a failure is encountered
     );
 
