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 |