OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/thread_local_storage.h" | 5 #include "base/threading/thread_local_storage.h" |
6 | 6 |
7 #include <windows.h> | 7 #include <windows.h> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 | 10 |
| 11 namespace base { |
| 12 |
11 // In order to make TLS destructors work, we need to keep function | 13 // In order to make TLS destructors work, we need to keep function |
12 // pointers to the destructor for each TLS that we allocate. | 14 // pointers to the destructor for each TLS that we allocate. |
13 // We make this work by allocating a single OS-level TLS, which | 15 // We make this work by allocating a single OS-level TLS, which |
14 // contains an array of slots for the application to use. In | 16 // contains an array of slots for the application to use. In |
15 // parallel, we also allocate an array of destructors, which we | 17 // parallel, we also allocate an array of destructors, which we |
16 // keep track of and call when threads terminate. | 18 // keep track of and call when threads terminate. |
17 | 19 |
18 // tls_key_ is the one native TLS that we use. It stores our | 20 // tls_key_ is the one native TLS that we use. It stores our |
19 // table. | 21 // table. |
20 long ThreadLocalStorage::tls_key_ = TLS_OUT_OF_INDEXES; | 22 long ThreadLocalStorage::tls_key_ = TLS_OUT_OF_INDEXES; |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
115 tls_destructors_[slot](value); | 117 tls_destructors_[slot](value); |
116 } | 118 } |
117 } | 119 } |
118 | 120 |
119 delete[] tls_data; | 121 delete[] tls_data; |
120 | 122 |
121 // In case there are other "onexit" handlers... | 123 // In case there are other "onexit" handlers... |
122 TlsSetValue(tls_key_, NULL); | 124 TlsSetValue(tls_key_, NULL); |
123 } | 125 } |
124 | 126 |
| 127 } // namespace base |
| 128 |
125 // Thread Termination Callbacks. | 129 // Thread Termination Callbacks. |
126 // Windows doesn't support a per-thread destructor with its | 130 // Windows doesn't support a per-thread destructor with its |
127 // TLS primitives. So, we build it manually by inserting a | 131 // TLS primitives. So, we build it manually by inserting a |
128 // function to be called on each thread's exit. | 132 // function to be called on each thread's exit. |
129 // This magic is from http://www.codeproject.com/threads/tls.asp | 133 // This magic is from http://www.codeproject.com/threads/tls.asp |
130 // and it works for VC++ 7.0 and later. | 134 // and it works for VC++ 7.0 and later. |
131 | 135 |
132 // Force a reference to _tls_used to make the linker create the TLS directory | 136 // Force a reference to _tls_used to make the linker create the TLS directory |
133 // if it's not already there. (e.g. if __declspec(thread) is not used). | 137 // if it's not already there. (e.g. if __declspec(thread) is not used). |
134 // Force a reference to p_thread_callback_base to prevent whole program | 138 // Force a reference to p_thread_callback_base to prevent whole program |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
185 #else // _WIN64 | 189 #else // _WIN64 |
186 | 190 |
187 #pragma data_seg(".CRT$XLB") | 191 #pragma data_seg(".CRT$XLB") |
188 PIMAGE_TLS_CALLBACK p_thread_callback_base = OnThreadExit; | 192 PIMAGE_TLS_CALLBACK p_thread_callback_base = OnThreadExit; |
189 | 193 |
190 // Reset the default section. | 194 // Reset the default section. |
191 #pragma data_seg() | 195 #pragma data_seg() |
192 | 196 |
193 #endif // _WIN64 | 197 #endif // _WIN64 |
194 } // extern "C" | 198 } // extern "C" |
OLD | NEW |