From 3e5b4084b8863bdb5be2bb5eefb39eff2e3c1b3e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= <sebastien@dynare.org>
Date: Fri, 1 Feb 2019 23:36:35 +0100
Subject: [PATCH] Dynare++: fix bug in new threading code

At the end of a thread, we must first notify the main thread waiting on the
condition variable, then unlock the mutex. We must do these two operations in
that order, otherwise there is a possibility of having the main process
destroying the condition variable before the thread tries to notify it (if all
other threads terminate at the same time and bring the counter down to zero).
For that reason, we cannot use std::notify_all_at_thread_exit().

Bug introduced in commit 752a02a36.
---
 dynare++/tl/cc/sthread.cc | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/dynare++/tl/cc/sthread.cc b/dynare++/tl/cc/sthread.cc
index 36e21b9f3..751e77f54 100644
--- a/dynare++/tl/cc/sthread.cc
+++ b/dynare++/tl/cc/sthread.cc
@@ -28,7 +28,15 @@ namespace sthread
             (*it)->operator()(mut_threads);
             std::unique_lock<std::mutex> lk2{mut_cv};
             counter--;
-            std::notify_all_at_thread_exit(cv, std::move(lk2));
+            /* First notify the thread waiting on the condition variable, then
+               unlock the mutex. We must do these two operations in that order,
+               otherwise there is a possibility of having the main process
+               destroying the condition variable before the thread tries to
+               notify it (if all other threads terminate at the same time and
+               bring the counter down to zero).
+               For that reason, we cannot use std::notify_all_at_thread_exit() */
+            cv.notify_one();
+            lk2.unlock();
           }};
         th.detach();
         ++it;
-- 
GitLab