}
// 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);
}
}
- /* 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);
}