| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/threading/thread_local_storage.h" | 5 #include "base/threading/thread_local_storage.h" |
| 6 | 6 |
| 7 #include "base/atomicops.h" | 7 #include "base/atomicops.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 | 9 |
| 10 using base::internal::PlatformThreadLocalStorage; | 10 using base::internal::PlatformThreadLocalStorage; |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 133 need_to_scan_destructors = false; | 133 need_to_scan_destructors = false; |
| 134 // Try to destroy the first-created-slot (which is slot 1) in our last | 134 // Try to destroy the first-created-slot (which is slot 1) in our last |
| 135 // destructor call. That user was able to function, and define a slot with | 135 // destructor call. That user was able to function, and define a slot with |
| 136 // no other services running, so perhaps it is a basic service (like an | 136 // no other services running, so perhaps it is a basic service (like an |
| 137 // allocator) and should also be destroyed last. If we get the order wrong, | 137 // allocator) and should also be destroyed last. If we get the order wrong, |
| 138 // then we'll itterate several more times, so it is really not that | 138 // then we'll itterate several more times, so it is really not that |
| 139 // critical (but it might help). | 139 // critical (but it might help). |
| 140 base::subtle::Atomic32 last_used_tls_key = | 140 base::subtle::Atomic32 last_used_tls_key = |
| 141 base::subtle::NoBarrier_Load(&g_last_used_tls_key); | 141 base::subtle::NoBarrier_Load(&g_last_used_tls_key); |
| 142 for (int slot = last_used_tls_key; slot > 0; --slot) { | 142 for (int slot = last_used_tls_key; slot > 0; --slot) { |
| 143 void* value = stack_allocated_tls_data[slot]; | 143 void* tls_value = stack_allocated_tls_data[slot]; |
| 144 if (value == NULL) | 144 if (tls_value == NULL) |
| 145 continue; | 145 continue; |
| 146 | 146 |
| 147 base::ThreadLocalStorage::TLSDestructorFunc destructor = | 147 base::ThreadLocalStorage::TLSDestructorFunc destructor = |
| 148 g_tls_destructors[slot]; | 148 g_tls_destructors[slot]; |
| 149 if (destructor == NULL) | 149 if (destructor == NULL) |
| 150 continue; | 150 continue; |
| 151 stack_allocated_tls_data[slot] = NULL; // pre-clear the slot. | 151 stack_allocated_tls_data[slot] = NULL; // pre-clear the slot. |
| 152 destructor(value); | 152 destructor(tls_value); |
| 153 // Any destructor might have called a different service, which then set | 153 // Any destructor might have called a different service, which then set |
| 154 // a different slot to a non-NULL value. Hence we need to check | 154 // a different slot to a non-NULL value. Hence we need to check |
| 155 // the whole vector again. This is a pthread standard. | 155 // the whole vector again. This is a pthread standard. |
| 156 need_to_scan_destructors = true; | 156 need_to_scan_destructors = true; |
| 157 } | 157 } |
| 158 if (--remaining_attempts <= 0) { | 158 if (--remaining_attempts <= 0) { |
| 159 NOTREACHED(); // Destructors might not have been called. | 159 NOTREACHED(); // Destructors might not have been called. |
| 160 break; | 160 break; |
| 161 } | 161 } |
| 162 } | 162 } |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 241 PlatformThreadLocalStorage::GetTLSValue( | 241 PlatformThreadLocalStorage::GetTLSValue( |
| 242 base::subtle::NoBarrier_Load(&g_native_tls_key))); | 242 base::subtle::NoBarrier_Load(&g_native_tls_key))); |
| 243 if (!tls_data) | 243 if (!tls_data) |
| 244 tls_data = ConstructTlsVector(); | 244 tls_data = ConstructTlsVector(); |
| 245 DCHECK_GT(slot_, 0); | 245 DCHECK_GT(slot_, 0); |
| 246 DCHECK_LT(slot_, kThreadLocalStorageSize); | 246 DCHECK_LT(slot_, kThreadLocalStorageSize); |
| 247 tls_data[slot_] = value; | 247 tls_data[slot_] = value; |
| 248 } | 248 } |
| 249 | 249 |
| 250 } // namespace base | 250 } // namespace base |
| OLD | NEW |