OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 <windows.h> | 7 #include <windows.h> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 | 10 |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
79 // Ensure that any rentrant calls change the temp version. | 79 // Ensure that any rentrant calls change the temp version. |
80 TlsSetValue(tls_key_, stack_allocated_tls_data); | 80 TlsSetValue(tls_key_, stack_allocated_tls_data); |
81 | 81 |
82 // Allocate an array to store our data. | 82 // Allocate an array to store our data. |
83 void** tls_data = new void*[kThreadLocalStorageSize]; | 83 void** tls_data = new void*[kThreadLocalStorageSize]; |
84 memcpy(tls_data, stack_allocated_tls_data, sizeof(stack_allocated_tls_data)); | 84 memcpy(tls_data, stack_allocated_tls_data, sizeof(stack_allocated_tls_data)); |
85 TlsSetValue(tls_key_, tls_data); | 85 TlsSetValue(tls_key_, tls_data); |
86 return tls_data; | 86 return tls_data; |
87 } | 87 } |
88 | 88 |
89 ThreadLocalStorage::Slot::Slot(TLSDestructorFunc destructor) | 89 ThreadLocalStorage::Slot::Slot(TLSDestructorFunc destructor) { |
90 : initialized_(false), | 90 initialized_ = false; |
91 slot_(0) { | 91 slot_ = 0; |
92 Initialize(destructor); | 92 Initialize(destructor); |
93 } | 93 } |
94 | 94 |
95 bool ThreadLocalStorage::Slot::Initialize(TLSDestructorFunc destructor) { | 95 bool ThreadLocalStorage::StaticSlot::Initialize(TLSDestructorFunc destructor) { |
96 if (tls_key_ == TLS_OUT_OF_INDEXES || !TlsGetValue(tls_key_)) | 96 if (tls_key_ == TLS_OUT_OF_INDEXES || !TlsGetValue(tls_key_)) |
97 ThreadLocalStorage::Initialize(); | 97 ThreadLocalStorage::Initialize(); |
98 | 98 |
99 // Grab a new slot. | 99 // Grab a new slot. |
100 slot_ = InterlockedIncrement(&tls_max_) - 1; | 100 slot_ = InterlockedIncrement(&tls_max_) - 1; |
101 DCHECK_GT(slot_, 0); | 101 DCHECK_GT(slot_, 0); |
102 if (slot_ >= kThreadLocalStorageSize) { | 102 if (slot_ >= kThreadLocalStorageSize) { |
103 NOTREACHED(); | 103 NOTREACHED(); |
104 return false; | 104 return false; |
105 } | 105 } |
106 | 106 |
107 // Setup our destructor. | 107 // Setup our destructor. |
108 g_tls_destructors[slot_] = destructor; | 108 g_tls_destructors[slot_] = destructor; |
109 initialized_ = true; | 109 initialized_ = true; |
110 return true; | 110 return true; |
111 } | 111 } |
112 | 112 |
113 void ThreadLocalStorage::Slot::Free() { | 113 void ThreadLocalStorage::StaticSlot::Free() { |
114 // At this time, we don't reclaim old indices for TLS slots. | 114 // At this time, we don't reclaim old indices for TLS slots. |
115 // So all we need to do is wipe the destructor. | 115 // So all we need to do is wipe the destructor. |
116 DCHECK_GT(slot_, 0); | 116 DCHECK_GT(slot_, 0); |
117 DCHECK_LT(slot_, kThreadLocalStorageSize); | 117 DCHECK_LT(slot_, kThreadLocalStorageSize); |
118 g_tls_destructors[slot_] = NULL; | 118 g_tls_destructors[slot_] = NULL; |
119 slot_ = 0; | 119 slot_ = 0; |
120 initialized_ = false; | 120 initialized_ = false; |
121 } | 121 } |
122 | 122 |
123 void* ThreadLocalStorage::Slot::Get() const { | 123 void* ThreadLocalStorage::StaticSlot::Get() const { |
124 void** tls_data = static_cast<void**>(TlsGetValue(tls_key_)); | 124 void** tls_data = static_cast<void**>(TlsGetValue(tls_key_)); |
125 if (!tls_data) | 125 if (!tls_data) |
126 tls_data = ThreadLocalStorage::Initialize(); | 126 tls_data = ThreadLocalStorage::Initialize(); |
127 DCHECK_GT(slot_, 0); | 127 DCHECK_GT(slot_, 0); |
128 DCHECK_LT(slot_, kThreadLocalStorageSize); | 128 DCHECK_LT(slot_, kThreadLocalStorageSize); |
129 return tls_data[slot_]; | 129 return tls_data[slot_]; |
130 } | 130 } |
131 | 131 |
132 void ThreadLocalStorage::Slot::Set(void* value) { | 132 void ThreadLocalStorage::StaticSlot::Set(void* value) { |
133 void** tls_data = static_cast<void**>(TlsGetValue(tls_key_)); | 133 void** tls_data = static_cast<void**>(TlsGetValue(tls_key_)); |
134 if (!tls_data) | 134 if (!tls_data) |
135 tls_data = ThreadLocalStorage::Initialize(); | 135 tls_data = ThreadLocalStorage::Initialize(); |
136 DCHECK_GT(slot_, 0); | 136 DCHECK_GT(slot_, 0); |
137 DCHECK_LT(slot_, kThreadLocalStorageSize); | 137 DCHECK_LT(slot_, kThreadLocalStorageSize); |
138 tls_data[slot_] = value; | 138 tls_data[slot_] = value; |
139 } | 139 } |
140 | 140 |
141 void ThreadLocalStorage::ThreadExit() { | 141 void ThreadLocalStorage::ThreadExit() { |
142 if (tls_key_ == TLS_OUT_OF_INDEXES) | 142 if (tls_key_ == TLS_OUT_OF_INDEXES) |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
261 #else // _WIN64 | 261 #else // _WIN64 |
262 | 262 |
263 #pragma data_seg(".CRT$XLB") | 263 #pragma data_seg(".CRT$XLB") |
264 PIMAGE_TLS_CALLBACK p_thread_callback_base = OnThreadExit; | 264 PIMAGE_TLS_CALLBACK p_thread_callback_base = OnThreadExit; |
265 | 265 |
266 // Reset the default section. | 266 // Reset the default section. |
267 #pragma data_seg() | 267 #pragma data_seg() |
268 | 268 |
269 #endif // _WIN64 | 269 #endif // _WIN64 |
270 } // extern "C" | 270 } // extern "C" |
OLD | NEW |