From: Carl Hetherington Date: Fri, 2 Oct 2015 09:06:48 +0000 (+0100) Subject: Speculative fix for hangs during Encoder::end(). X-Git-Tag: v2.3.13~4 X-Git-Url: https://main.carlh.net/gitweb/?p=dcpomatic.git;a=commitdiff_plain;h=aac97a7653003ab7032d927eeb236cff4ad726d1 Speculative fix for hangs during Encoder::end(). I think it's possible that, if an exception is thrown by an Encoder thread during the clear-out loop at the top of Encoder::end, that loop will hang waiting for a notify() on _full_condition that never comes. Fix this by rethrow()ing in this loop and notifying _full_condition if an encoder thread throws an exception. --- diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index 6fe745dd7..ef58ca09e 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -43,6 +43,7 @@ #include "i18n.h" #define LOG_GENERAL(...) _film->log()->log (String::compose (__VA_ARGS__), Log::TYPE_GENERAL); +#define LOG_GENERAL_NC(...) _film->log()->log (__VA_ARGS__, Log::TYPE_GENERAL); #define LOG_ERROR(...) _film->log()->log (String::compose (__VA_ARGS__), Log::TYPE_ERROR); #define LOG_TIMING(...) _film->log()->microsecond_log (String::compose (__VA_ARGS__), Log::TYPE_TIMING); @@ -95,12 +96,15 @@ Encoder::end () /* Keep waking workers until the queue is empty */ while (!_queue.empty ()) { + rethrow (); _empty_condition.notify_all (); _full_condition.wait (lock); } lock.unlock (); + LOG_GENERAL_NC (N_("Terminating encoder threads")); + terminate_threads (); LOG_GENERAL (N_("Mopping up %1"), _queue.size()); @@ -373,6 +377,8 @@ try catch (...) { store_current (); + /* Wake anything waiting on _full_condition so it can see the exception */ + _full_condition.notify_all (); } void