From 491fb1cf0ce8c9333594e6c364044f20fff819de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= <sebastien@dynare.org> Date: Tue, 29 Apr 2025 14:51:13 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20perfect=5Fforesight=5Fproblem=20?= =?UTF-8?q?MEX:=20error=20mechanism=20now=20thread-safe?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../perfect_foresight_problem/DynamicModelCaller.cc | 7 ++++++- .../perfect_foresight_problem/DynamicModelCaller.hh | 4 +++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/mex/sources/perfect_foresight_problem/DynamicModelCaller.cc b/mex/sources/perfect_foresight_problem/DynamicModelCaller.cc index 0879b6241f..4ed7b9be9e 100644 --- a/mex/sources/perfect_foresight_problem/DynamicModelCaller.cc +++ b/mex/sources/perfect_foresight_problem/DynamicModelCaller.cc @@ -1,5 +1,5 @@ /* - * Copyright © 2019-2024 Dynare Team + * Copyright © 2019-2025 Dynare Team * * This file is part of Dynare. * @@ -26,6 +26,7 @@ using namespace std::literals::string_literals; std::string DynamicModelCaller::error_msg; +std::mutex DynamicModelCaller::error_mtx; #if !defined(_WIN32) && !defined(__CYGWIN32__) void* DynamicModelDllCaller::resid_mex {nullptr}; @@ -210,12 +211,14 @@ DynamicModelMatlabCaller::eval(double* resid) funcname.c_str())}; if (exception) { + std::lock_guard lk {error_mtx}; error_msg = "An error occurred when calling " + funcname; return; // Avoid manipulating null pointers in plhs, see #1832 } if (!mxIsDouble(plhs[0]) || mxIsSparse(plhs[0])) { + std::lock_guard lk {error_mtx}; error_msg = "Residuals should be a dense array of double floats"; return; } @@ -249,6 +252,7 @@ DynamicModelMatlabCaller::eval(double* resid) funcname.c_str())}; if (exception) { + std::lock_guard lk {error_mtx}; error_msg = "An error occurred when calling " + funcname; return; // Avoid manipulating null pointers in plhs, see #1832 } @@ -261,6 +265,7 @@ DynamicModelMatlabCaller::eval(double* resid) if (!mxIsDouble(plhs[0]) || !mxIsSparse(plhs[0])) { + std::lock_guard lk {error_mtx}; error_msg = "Jacobian should be a sparse array of double floats"; return; } diff --git a/mex/sources/perfect_foresight_problem/DynamicModelCaller.hh b/mex/sources/perfect_foresight_problem/DynamicModelCaller.hh index b651ec59a2..09612b4d69 100644 --- a/mex/sources/perfect_foresight_problem/DynamicModelCaller.hh +++ b/mex/sources/perfect_foresight_problem/DynamicModelCaller.hh @@ -1,5 +1,5 @@ /* - * Copyright © 2019-2024 Dynare Team + * Copyright © 2019-2025 Dynare Team * * This file is part of Dynare. * @@ -23,6 +23,7 @@ #include <algorithm> #include <limits> #include <memory> +#include <mutex> #include <string> #include <type_traits> #include <vector> @@ -47,6 +48,7 @@ public: // Used to store error messages (as exceptions cannot cross the OpenMP boundary) static std::string error_msg; + static std::mutex error_mtx; // Guard for access in OpenMP context DynamicModelCaller(bool linear_arg, bool compute_jacobian_arg) : linear {linear_arg}, compute_jacobian {compute_jacobian_arg} -- GitLab