aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/src
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely.gcc@gmail.com>2009-05-05 21:32:38 +0000
committerJonathan Wakely <redi@gcc.gnu.org>2009-05-05 22:32:38 +0100
commitefdb734755a28bf494a0e375e9fec6d1012482b4 (patch)
tree7872cbd2d5e29eb4cc6cb620d05574769ca67a24 /libstdc++-v3/src
parent32f579f6ebde02d94ac8fbd0379b1d0207dd9ac5 (diff)
downloadgcc-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.cc34
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();
}