| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "platform/globals.h" // NOLINT | 5 #include "platform/globals.h" // NOLINT |
| 6 #if defined(TARGET_OS_WINDOWS) | 6 #if defined(TARGET_OS_WINDOWS) |
| 7 | 7 |
| 8 #include "vm/growable_array.h" | 8 #include "vm/growable_array.h" |
| 9 #include "vm/lockers.h" |
| 9 #include "vm/os_thread.h" | 10 #include "vm/os_thread.h" |
| 10 | 11 |
| 11 #include <process.h> // NOLINT | 12 #include <process.h> // NOLINT |
| 12 | 13 |
| 13 #include "platform/assert.h" | 14 #include "platform/assert.h" |
| 14 | 15 |
| 15 namespace dart { | 16 namespace dart { |
| 16 | 17 |
| 17 // This flag is flipped by platform_win.cc when the process is exiting. | 18 // This flag is flipped by platform_win.cc when the process is exiting. |
| 18 // TODO(zra): Remove once VM shuts down cleanly. | 19 // TODO(zra): Remove once VM shuts down cleanly. |
| (...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 558 } | 559 } |
| 559 | 560 |
| 560 | 561 |
| 561 void ThreadLocalData::AddThreadLocal(ThreadLocalKey key, | 562 void ThreadLocalData::AddThreadLocal(ThreadLocalKey key, |
| 562 ThreadDestructor destructor) { | 563 ThreadDestructor destructor) { |
| 563 ASSERT(thread_locals_ != NULL); | 564 ASSERT(thread_locals_ != NULL); |
| 564 if (destructor == NULL) { | 565 if (destructor == NULL) { |
| 565 // We only care about thread locals with destructors. | 566 // We only care about thread locals with destructors. |
| 566 return; | 567 return; |
| 567 } | 568 } |
| 568 mutex_->Lock(); | 569 MutexLocker ml(mutex_, false); |
| 569 #if defined(DEBUG) | 570 #if defined(DEBUG) |
| 570 // Verify that we aren't added twice. | 571 // Verify that we aren't added twice. |
| 571 for (intptr_t i = 0; i < thread_locals_->length(); i++) { | 572 for (intptr_t i = 0; i < thread_locals_->length(); i++) { |
| 572 const ThreadLocalEntry& entry = thread_locals_->At(i); | 573 const ThreadLocalEntry& entry = thread_locals_->At(i); |
| 573 ASSERT(entry.key() != key); | 574 ASSERT(entry.key() != key); |
| 574 } | 575 } |
| 575 #endif | 576 #endif |
| 576 // Add to list. | 577 // Add to list. |
| 577 thread_locals_->Add(ThreadLocalEntry(key, destructor)); | 578 thread_locals_->Add(ThreadLocalEntry(key, destructor)); |
| 578 mutex_->Unlock(); | |
| 579 } | 579 } |
| 580 | 580 |
| 581 | 581 |
| 582 void ThreadLocalData::RemoveThreadLocal(ThreadLocalKey key) { | 582 void ThreadLocalData::RemoveThreadLocal(ThreadLocalKey key) { |
| 583 ASSERT(thread_locals_ != NULL); mutex_->Lock(); | 583 ASSERT(thread_locals_ != NULL); |
| 584 MutexLocker ml(mutex_, false); |
| 584 intptr_t i = 0; | 585 intptr_t i = 0; |
| 585 for (; i < thread_locals_->length(); i++) { | 586 for (; i < thread_locals_->length(); i++) { |
| 586 const ThreadLocalEntry& entry = thread_locals_->At(i); | 587 const ThreadLocalEntry& entry = thread_locals_->At(i); |
| 587 if (entry.key() == key) { | 588 if (entry.key() == key) { |
| 588 break; | 589 break; |
| 589 } | 590 } |
| 590 } | 591 } |
| 591 if (i == thread_locals_->length()) { | 592 if (i == thread_locals_->length()) { |
| 592 // Not found. | 593 // Not found. |
| 593 mutex_->Unlock(); | |
| 594 return; | 594 return; |
| 595 } | 595 } |
| 596 thread_locals_->RemoveAt(i); | 596 thread_locals_->RemoveAt(i); |
| 597 mutex_->Unlock(); | |
| 598 } | 597 } |
| 599 | 598 |
| 600 | 599 |
| 601 // This function is executed on the thread that is exiting. It is invoked | 600 // This function is executed on the thread that is exiting. It is invoked |
| 602 // by |OnDartThreadExit| (see below for notes on TLS destructors on Windows). | 601 // by |OnDartThreadExit| (see below for notes on TLS destructors on Windows). |
| 603 void ThreadLocalData::RunDestructors() { | 602 void ThreadLocalData::RunDestructors() { |
| 604 ASSERT(thread_locals_ != NULL); | 603 ASSERT(thread_locals_ != NULL); |
| 605 ASSERT(mutex_ != NULL); | 604 ASSERT(mutex_ != NULL); |
| 606 mutex_->Lock(); | 605 MutexLocker ml(mutex_, false); |
| 607 for (intptr_t i = 0; i < thread_locals_->length(); i++) { | 606 for (intptr_t i = 0; i < thread_locals_->length(); i++) { |
| 608 const ThreadLocalEntry& entry = thread_locals_->At(i); | 607 const ThreadLocalEntry& entry = thread_locals_->At(i); |
| 609 // We access the exiting thread's TLS variable here. | 608 // We access the exiting thread's TLS variable here. |
| 610 void* p = reinterpret_cast<void*>(OSThread::GetThreadLocal(entry.key())); | 609 void* p = reinterpret_cast<void*>(OSThread::GetThreadLocal(entry.key())); |
| 611 // We invoke the constructor here. | 610 // We invoke the constructor here. |
| 612 entry.destructor()(p); | 611 entry.destructor()(p); |
| 613 } | 612 } |
| 614 mutex_->Unlock(); | |
| 615 } | 613 } |
| 616 | 614 |
| 617 | 615 |
| 618 Mutex* ThreadLocalData::mutex_ = NULL; | 616 Mutex* ThreadLocalData::mutex_ = NULL; |
| 619 MallocGrowableArray<ThreadLocalEntry>* ThreadLocalData::thread_locals_ = NULL; | 617 MallocGrowableArray<ThreadLocalEntry>* ThreadLocalData::thread_locals_ = NULL; |
| 620 | 618 |
| 621 | 619 |
| 622 void ThreadLocalData::InitOnce() { | 620 void ThreadLocalData::InitOnce() { |
| 623 mutex_ = new Mutex(); | 621 mutex_ = new Mutex(); |
| 624 thread_locals_ = new MallocGrowableArray<ThreadLocalEntry>(); | 622 thread_locals_ = new MallocGrowableArray<ThreadLocalEntry>(); |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 713 #pragma data_seg(".CRT$XLB") | 711 #pragma data_seg(".CRT$XLB") |
| 714 PIMAGE_TLS_CALLBACK p_thread_callback_dart = OnDartThreadExit; | 712 PIMAGE_TLS_CALLBACK p_thread_callback_dart = OnDartThreadExit; |
| 715 | 713 |
| 716 // Reset the default section. | 714 // Reset the default section. |
| 717 #pragma data_seg() | 715 #pragma data_seg() |
| 718 | 716 |
| 719 #endif // _WIN64 | 717 #endif // _WIN64 |
| 720 } // extern "C" | 718 } // extern "C" |
| 721 | 719 |
| 722 #endif // defined(TARGET_OS_WINDOWS) | 720 #endif // defined(TARGET_OS_WINDOWS) |
| OLD | NEW |