diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2016-12-13 16:39:58 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2016-12-13 16:39:58 +0200 |
commit | a4199b808fd678f74935d540490eae9dc78a9ffe (patch) | |
tree | 16d1f0e583c926838b92722e000fae2c1ac4aa9e /butl/utility | |
parent | b05e24a7f512c1f005dbcb67b3fce8b3d16e110e (diff) |
Fix thread safety issue
Diffstat (limited to 'butl/utility')
-rw-r--r-- | butl/utility | 46 |
1 files changed, 36 insertions, 10 deletions
diff --git a/butl/utility b/butl/utility index c57aabb..02d9331 100644 --- a/butl/utility +++ b/butl/utility @@ -9,10 +9,11 @@ #include <cstddef> // size_t #include <utility> // move(), forward() #include <cstring> // strcmp(), strlen() -#include <exception> // uncaught_exception() +#include <exception> // uncaught_exception(s)() //#include <functional> // hash #include <butl/export> +#include <butl/config> 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 <typename F> struct exception_guard; @@ -172,6 +164,39 @@ namespace butl return exception_guard<F> (std::move (f)); } +#ifdef BUTL_CXX17_UNCAUGHT_EXCEPTIONS + template <typename F> + 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 <typename F> struct exception_guard { @@ -189,6 +214,7 @@ namespace butl private: F f_; }; +#endif } #include <butl/utility.ixx> |