From 7124866a4fd6ac2e2789386c9bbc5ca40216f709 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Sat, 7 Jun 2014 20:34:18 -0700 Subject: [PATCH] fix(library/module): potential deadlock when child thread threw an exception Signed-off-by: Leonardo de Moura --- src/library/module.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/library/module.cpp b/src/library/module.cpp index 670a8bdb3..65117e76d 100644 --- a/src/library/module.cpp +++ b/src/library/module.cpp @@ -358,23 +358,29 @@ struct import_modules_fn { return; std::vector> extra_threads; std::vector> thread_exceptions(m_num_threads - 1); + atomic failed_thread_idx(-1); // >= 0 if error for (unsigned i = 0; i < m_num_threads - 1; i++) { - extra_threads.push_back(std::unique_ptr(new interruptible_thread([=, &thread_exceptions]() { + extra_threads.push_back(std::unique_ptr(new interruptible_thread([=, &thread_exceptions, &failed_thread_idx]() { try { while (auto t = next_task()) { (*t)(m_senv); } m_asynch_cv.notify_all(); - } catch (exception ex) { + } catch (exception & ex) { thread_exceptions[i].reset(ex.clone()); + failed_thread_idx = i; } catch (...) { thread_exceptions[i].reset(new exception("module import thread failed for unknown reasons")); + failed_thread_idx = i; } }))); } try { while (auto t = next_task()) { (*t)(m_senv); + int idx = failed_thread_idx; + if (idx >= 0) + thread_exceptions[idx]->rethrow(); } m_asynch_cv.notify_all(); for (auto & th : extra_threads) @@ -386,10 +392,6 @@ struct import_modules_fn { th->join(); throw; } - for (auto const & ex : thread_exceptions) { - if (ex.get()) - ex->rethrow(); - } } environment process_delayed_tasks() {