Use thread wait primitives for worker thread shutdown.

Avoids possible issues due to tasks interleaving the shutdown on the same thread.
This commit is contained in:
Sönke Ludwig 2017-02-23 14:43:22 +01:00
parent 3dbdc90927
commit b995bdaa72
No known key found for this signature in database
GPG key ID: D95E8DB493EE314C

View file

@ -66,8 +66,22 @@ shared class TaskPool {
m_signal.emit(); m_signal.emit();
auto ec = m_signal.emitCount; auto ec = m_signal.emitCount;
while (m_state.lock.threads.length > 0) while (true) {
ec = m_signal.waitUninterruptible(ec); WorkerThread th;
with (m_state.lock)
if (threads.length) {
th = threads[0];
threads = threads[1 .. $];
}
if (!th) break;
() @trusted {
try th.join();
catch (Exception e) {
logWarn("Failed to wait for worker thread exit: %s", e.msg);
}
} ();
}
size_t cnt = m_state.lock.queue.length; size_t cnt = m_state.lock.queue.length;
if (cnt > 0) logWarn("There were still %d worker tasks pending at exit.", cnt); if (cnt > 0) logWarn("There were still %d worker tasks pending at exit.", cnt);
@ -290,7 +304,6 @@ private class WorkerThread : Thread {
if (threads.length > 0 && !queue.empty) if (threads.length > 0 && !queue.empty)
logWarn("Worker threads shut down with worker tasks still left in the queue."); logWarn("Worker threads shut down with worker tasks still left in the queue.");
} }
m_pool.m_signal.emit();
exitEventLoop(); exitEventLoop();
} }