diff options
author | Jonathan Wakely <jwakely.gcc@gmail.com> | 2009-05-05 21:32:38 +0000 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2009-05-05 22:32:38 +0100 |
commit | efdb734755a28bf494a0e375e9fec6d1012482b4 (patch) | |
tree | 7872cbd2d5e29eb4cc6cb620d05574769ca67a24 /libstdc++-v3/src | |
parent | 32f579f6ebde02d94ac8fbd0379b1d0207dd9ac5 (diff) | |
download | gcc-efdb734755a28bf494a0e375e9fec6d1012482b4.zip gcc-efdb734755a28bf494a0e375e9fec6d1012482b4.tar.gz gcc-efdb734755a28bf494a0e375e9fec6d1012482b4.tar.bz2 |
re PR libstdc++/39909 (non-TLS version of std::call_once causes terminate)
2009-05-05 Jonathan Wakely <jwakely.gcc@gmail.com>
PR libstdc++/39909
* include/std/mutex (__get_once_functor_lock, __get_once_mutex,
__set_once_functor_lock_ptr): Replace global lock object with local
locks on global mutex.
* src/mutex.cc (__get_once_functor_lock, __get_once_mutex,
__set_once_functor_lock_ptr): Likewise, keeping old function to
preserve ABI.
(__once_proxy): Use pointer to local lock if set, global lock
otherwise.
* config/abi/pre/gnu.ver: Add new symbols to new ABI version.
* testsuite/util/testsuite_abi.cc: Add GLIBCX_3.4.12 version.
* testsuite/30_threads/call_once/39909.cc: New.
From-SVN: r147137
Diffstat (limited to 'libstdc++-v3/src')
-rw-r--r-- | libstdc++-v3/src/mutex.cc | 34 |
1 files changed, 28 insertions, 6 deletions
diff --git a/libstdc++-v3/src/mutex.cc b/libstdc++-v3/src/mutex.cc index e0a9489..fcc1eb9 100644 --- a/libstdc++-v3/src/mutex.cc +++ b/libstdc++-v3/src/mutex.cc @@ -28,11 +28,11 @@ #ifndef _GLIBCXX_HAVE_TLS namespace { - std::mutex& - get_once_mutex() + inline std::unique_lock<std::mutex>*& + __get_once_functor_lock_ptr() { - static std::mutex once_mutex; - return once_mutex; + static std::unique_lock<std::mutex>* __once_functor_lock_ptr = 0; + return __once_functor_lock_ptr; } } #endif @@ -55,10 +55,25 @@ namespace std template class function<void()>; function<void()> __once_functor; + mutex& + __get_once_mutex() + { + static mutex once_mutex; + return once_mutex; + } + + // code linked against ABI 3.4.12 and later uses this + void + __set_once_functor_lock_ptr(unique_lock<mutex>* __ptr) + { + __get_once_functor_lock_ptr() = __ptr; + } + + // unsafe - retained for compatibility with ABI 3.4.11 unique_lock<mutex>& __get_once_functor_lock() { - static unique_lock<mutex> once_functor_lock(get_once_mutex(), defer_lock); + static unique_lock<mutex> once_functor_lock(__get_once_mutex(), defer_lock); return once_functor_lock; } #endif @@ -69,7 +84,14 @@ namespace std { #ifndef _GLIBCXX_HAVE_TLS function<void()> __once_call = std::move(__once_functor); - __get_once_functor_lock().unlock(); + if (unique_lock<mutex>* __lock = __get_once_functor_lock_ptr()) + { + // caller is using new ABI and provided lock ptr + __get_once_functor_lock_ptr() = 0; + __lock->unlock(); + } + else + __get_once_functor_lock().unlock(); // global lock #endif __once_call(); } |