]> granicus.if.org Git - handbrake/commitdiff
potential fix for hard to reproduce crash
authorJohn Stebbins <jstebbins.hb@gmail.com>
Fri, 9 Dec 2016 01:53:58 +0000 (17:53 -0800)
committerJohn Stebbins <jstebbins.hb@gmail.com>
Sat, 17 Dec 2016 15:28:51 +0000 (07:28 -0800)
libhb/work.c

index 7d43ce4c5e0c69853ca8127f2eff223b2e519a0b..1cfb08bb1bd6c18a2874c94a53bc815f32b36086 100644 (file)
@@ -1734,6 +1734,9 @@ static void do_job(hb_job_t *job)
     }
 
     // Wait for the thread of the last work object to complete
+    // Note that other threads may still be running even though the
+    // last thread has exited. So we must be careful with the sequence
+    // of closing threads below.
     w = hb_list_item(job->list_work, hb_list_count(job->list_work) - 1);
     w->die = job->die;
     hb_thread_close(&w->thread);
@@ -1762,14 +1765,20 @@ cleanup:
         }
     }
 
-    /* Close work objects */
-    while ((w = hb_list_item(job->list_work, 0)))
+    // Close work objects
+    // A work thread can use data created by another work thread's init.
+    // So close all work threads before closing thread data.
+    for (i = 0; i < hb_list_count(job->list_work); i++)
     {
-        hb_list_rem(job->list_work, w);
+        w = hb_list_item(job->list_work, i);
         if (w->thread != NULL)
         {
             hb_thread_close(&w->thread);
         }
+    }
+    while ((w = hb_list_item(job->list_work, 0)))
+    {
+        hb_list_rem(job->list_work, w);
         w->close(w);
         free(w);
     }