]>
Commit | Line | Data |
---|---|---|
057bae2c | 1 | // mutex -*- C++ -*- |
2 | ||
f1717362 | 3 | // Copyright (C) 2008-2016 Free Software Foundation, Inc. |
057bae2c | 4 | // |
5 | // This file is part of the GNU ISO C++ Library. This library is free | |
6 | // software; you can redistribute it and/or modify it under the | |
7 | // terms of the GNU General Public License as published by the | |
6bc9506f | 8 | // Free Software Foundation; either version 3, or (at your option) |
057bae2c | 9 | // any later version. |
10 | ||
11 | // This library is distributed in the hope that it will be useful, | |
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | // GNU General Public License for more details. | |
15 | ||
6bc9506f | 16 | // Under Section 7 of GPL version 3, you are granted additional |
17 | // permissions described in the GCC Runtime Library Exception, version | |
18 | // 3.1, as published by the Free Software Foundation. | |
057bae2c | 19 | |
6bc9506f | 20 | // You should have received a copy of the GNU General Public License and |
21 | // a copy of the GCC Runtime Library Exception along with this program; | |
22 | // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see | |
23 | // <http://www.gnu.org/licenses/>. | |
057bae2c | 24 | |
25 | #include <mutex> | |
26 | ||
5cee5730 | 27 | #if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1) |
5c758b83 | 28 | #ifndef _GLIBCXX_HAVE_TLS |
29 | namespace | |
30 | { | |
975b5573 | 31 | inline std::unique_lock<std::mutex>*& |
32 | __get_once_functor_lock_ptr() | |
5c758b83 | 33 | { |
975b5573 | 34 | static std::unique_lock<std::mutex>* __once_functor_lock_ptr = 0; |
35 | return __once_functor_lock_ptr; | |
5c758b83 | 36 | } |
37 | } | |
38 | #endif | |
39 | ||
2948dd21 | 40 | namespace std _GLIBCXX_VISIBILITY(default) |
41 | { | |
42 | _GLIBCXX_BEGIN_NAMESPACE_VERSION | |
5022cf3f | 43 | |
5cee5730 | 44 | #ifdef _GLIBCXX_HAVE_TLS |
45 | __thread void* __once_callable; | |
46 | __thread void (*__once_call)(); | |
47 | #else | |
9e57b7da | 48 | // Explicit instantiation due to -fno-implicit-instantiation. |
5cee5730 | 49 | template class function<void()>; |
50 | function<void()> __once_functor; | |
9e57b7da | 51 | |
975b5573 | 52 | mutex& |
53 | __get_once_mutex() | |
54 | { | |
55 | static mutex once_mutex; | |
56 | return once_mutex; | |
57 | } | |
58 | ||
59 | // code linked against ABI 3.4.12 and later uses this | |
60 | void | |
61 | __set_once_functor_lock_ptr(unique_lock<mutex>* __ptr) | |
62 | { | |
63 | __get_once_functor_lock_ptr() = __ptr; | |
64 | } | |
65 | ||
66 | // unsafe - retained for compatibility with ABI 3.4.11 | |
5c758b83 | 67 | unique_lock<mutex>& |
68 | __get_once_functor_lock() | |
9e57b7da | 69 | { |
975b5573 | 70 | static unique_lock<mutex> once_functor_lock(__get_once_mutex(), defer_lock); |
5c758b83 | 71 | return once_functor_lock; |
9e57b7da | 72 | } |
5cee5730 | 73 | #endif |
74 | ||
75 | extern "C" | |
76 | { | |
77 | void __once_proxy() | |
78 | { | |
79 | #ifndef _GLIBCXX_HAVE_TLS | |
80 | function<void()> __once_call = std::move(__once_functor); | |
975b5573 | 81 | if (unique_lock<mutex>* __lock = __get_once_functor_lock_ptr()) |
82 | { | |
83 | // caller is using new ABI and provided lock ptr | |
84 | __get_once_functor_lock_ptr() = 0; | |
85 | __lock->unlock(); | |
86 | } | |
87 | else | |
88 | __get_once_functor_lock().unlock(); // global lock | |
5cee5730 | 89 | #endif |
90 | __once_call(); | |
91 | } | |
92 | } | |
5022cf3f | 93 | |
2948dd21 | 94 | _GLIBCXX_END_NAMESPACE_VERSION |
08709c1d | 95 | } // namespace std |
c0000147 | 96 | |
5cee5730 | 97 | #endif // _GLIBCXX_HAS_GTHREADS && _GLIBCXX_USE_C99_STDINT_TR1 |