From a4199b808fd678f74935d540490eae9dc78a9ffe Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 13 Dec 2016 16:39:58 +0200 Subject: Fix thread safety issue --- butl/utility | 46 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 10 deletions(-) (limited to 'butl/utility') diff --git a/butl/utility b/butl/utility index c57aabb..02d9331 100644 --- a/butl/utility +++ b/butl/utility @@ -9,10 +9,11 @@ #include // size_t #include // move(), forward() #include // strcmp(), strlen() -#include // uncaught_exception() +#include // uncaught_exception(s)() //#include // hash #include +#include namespace butl { @@ -153,15 +154,6 @@ namespace butl // Call a function if there is an exception. // - // True means we are in the body of a destructor that is being called as - // part of the exception stack unwindining. Used to compensate for the - // deficiencies of uncaught_exception() until C++17 uncaught_exceptions() - // becomes available. - // - // @@ MT: will have to be TLS. - // - LIBBUTL_EXPORT extern bool exception_unwinding_dtor; - template struct exception_guard; @@ -172,6 +164,39 @@ namespace butl return exception_guard (std::move (f)); } +#ifdef BUTL_CXX17_UNCAUGHT_EXCEPTIONS + template + struct exception_guard + { + exception_guard (F f) + : f_ (std::move (f)), + u_ (std::uncaught_exceptions ()) {} + + ~exception_guard () + { + if (u_ != std::uncaught_exceptions ()) + f_ (); + } + + private: + F f_; + int u_; + }; +#else + // Fallback implementation using a TLS flag. + // + // True means we are in the body of a destructor that is being called as + // part of the exception stack unwindining. + // + LIBBUTL_EXPORT + extern +#ifdef BUTL_CXX11_THREAD_LOCAL + thread_local +#else + __thread +#endif + bool exception_unwinding_dtor; + template struct exception_guard { @@ -189,6 +214,7 @@ namespace butl private: F f_; }; +#endif } #include -- cgit v1.1