Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(416)

Unified Diff: runtime/vm/os_thread_win.cc

Issue 1410493002: Complete support for Windows TLS destructors (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: runtime/vm/os_thread_win.cc
diff --git a/runtime/vm/os_thread_win.cc b/runtime/vm/os_thread_win.cc
index bcb5a5398138c38b67cd9f76942c2d0d9d2d755f..703c18c90cf0b8a763a04c804b8b2eb7d97e54a4 100644
--- a/runtime/vm/os_thread_win.cc
+++ b/runtime/vm/os_thread_win.cc
@@ -5,6 +5,7 @@
#include "platform/globals.h" // NOLINT
#if defined(TARGET_OS_WINDOWS)
+#include "vm/growable_array.h"
#include "vm/os_thread.h"
#include <process.h> // NOLINT
@@ -73,11 +74,12 @@ ThreadLocalKey OSThread::kUnsetThreadLocalKey = TLS_OUT_OF_INDEXES;
ThreadId OSThread::kInvalidThreadId = 0;
ThreadJoinId OSThread::kInvalidThreadJoinId = 0;
-ThreadLocalKey OSThread::CreateThreadLocal(ThreadDestructor unused) {
+ThreadLocalKey OSThread::CreateThreadLocal(ThreadDestructor destructor) {
ThreadLocalKey key = TlsAlloc();
if (key == kUnsetThreadLocalKey) {
FATAL1("TlsAlloc failed %d", GetLastError());
}
+ ThreadLocalData::AddThreadLocal(key, destructor);
return key;
}
@@ -88,6 +90,7 @@ void OSThread::DeleteThreadLocal(ThreadLocalKey key) {
if (!result) {
FATAL1("TlsFree failed %d", GetLastError());
}
+ ThreadLocalData::RemoveThreadLocal(key);
}
@@ -482,14 +485,88 @@ void Monitor::NotifyAll() {
data_.SignalAndRemoveAllWaiters();
}
-// This function is defined in thread.cc.
-extern void ThreadCleanupOnExit();
-} // namespace dart
+void ThreadLocalData::AddThreadLocal(ThreadLocalKey key,
+ ThreadDestructor destructor) {
+ if (thread_locals_ == NULL) {
+ return;
+ }
siva 2015/10/15 22:42:48 Should this be ASSERT(thread_locals_ != NULL);
Cutch 2015/10/16 16:53:25 Done.
+ if (destructor == NULL) {
+ // We only care about thread locals with destructors.
+ return;
+ }
+ mutex_->Lock();
+#if defined(DEBUG)
+ // Verify that we aren't added twice.
+ for (intptr_t i = 0; i < thread_locals_->length(); i++) {
+ const ThreadLocalEntry& entry = thread_locals_->At(i);
+ ASSERT(entry.key() != key);
+ }
+#endif
+ // Add to list.
+ thread_locals_->Add(ThreadLocalEntry(key, destructor));
+ mutex_->Unlock();
+}
-// NOTE: We still do not respect arbitrary TLS destructors on Windows, but,
-// we do run known TLS cleanup functions. See |OnThreadExit| below for
-// the list of functions that are called.
+
+void ThreadLocalData::RemoveThreadLocal(ThreadLocalKey key) {
+ if (thread_locals_ == NULL) {
+ return;
+ }
siva 2015/10/15 22:42:48 Ditto comment.
Cutch 2015/10/16 16:53:25 Done.
+ mutex_->Lock();
+ intptr_t i = 0;
+ for (; i < thread_locals_->length(); i++) {
+ const ThreadLocalEntry& entry = thread_locals_->At(i);
+ if (entry.key() == key) {
+ break;
+ }
+ }
+ if (i == thread_locals_->length()) {
+ // Not found.
+ mutex_->Unlock();
+ return;
+ }
+ thread_locals_->RemoveAt(i);
+ mutex_->Unlock();
+}
+
+
+void ThreadLocalData::RunDestructors() {
+ ASSERT(mutex_ != NULL);
+ mutex_->Lock();
+ ASSERT(thread_locals_ != NULL);
+ for (intptr_t i = 0; i < thread_locals_->length(); i++) {
+ const ThreadLocalEntry& entry = thread_locals_->At(i);
+ void* p = reinterpret_cast<void*>(OSThread::GetThreadLocal(entry.key()));
+ entry.destructor()(p);
+ }
+ mutex_->Unlock();
+}
+
+
+Mutex* ThreadLocalData::mutex_ = NULL;
+MallocGrowableArray<ThreadLocalEntry>* ThreadLocalData::thread_locals_ = NULL;
+
+
+void ThreadLocalData::InitOnce() {
+ mutex_ = new Mutex();
+ thread_locals_ = new MallocGrowableArray<ThreadLocalEntry>();
+}
+
+
+void ThreadLocalData::Shutdown() {
+ if (mutex_ != NULL) {
+ delete mutex_;
+ mutex_ = NULL;
+ }
+ if (thread_locals_ != NULL) {
+ delete thread_locals_;
+ thread_locals_ = NULL;
+ }
+}
+
+
+} // namespace dart
// The following was adapted from Chromium:
// src/base/threading/thread_local_storage_win.cc
@@ -522,7 +599,7 @@ void NTAPI OnDartThreadExit(PVOID module, DWORD reason, PVOID reserved) {
// On XP SP0 & SP1, the DLL_PROCESS_ATTACH is never seen. It is sent on SP2+
// and on W2K and W2K3. So don't assume it is sent.
if (DLL_THREAD_DETACH == reason || DLL_PROCESS_DETACH == reason) {
- dart::ThreadCleanupOnExit();
+ dart::ThreadLocalData::RunDestructors();
dart::MonitorWaitData::ThreadExit();
}
}

Powered by Google App Engine
This is Rietveld 408576698