Chromium Code Reviews| Index: runtime/vm/os_thread.cc |
| diff --git a/runtime/vm/os_thread.cc b/runtime/vm/os_thread.cc |
| index 3789a60140a269b738a4ccdd5ebedbe8f3834573..219287ebf8e51e7da92b9265501efed7b5cb5ddf 100644 |
| --- a/runtime/vm/os_thread.cc |
| +++ b/runtime/vm/os_thread.cc |
| @@ -16,6 +16,7 @@ namespace dart { |
| ThreadLocalKey OSThread::thread_key_ = kUnsetThreadLocalKey; |
| OSThread* OSThread::thread_list_head_ = NULL; |
| Mutex* OSThread::thread_list_lock_ = NULL; |
| +bool OSThread::creation_enabled_ = false; |
| OSThread::OSThread() : |
| @@ -31,7 +32,6 @@ OSThread::OSThread() : |
| log_(new class Log()), |
| stack_base_(0), |
| thread_(NULL) { |
| - AddThreadToList(this); |
| } |
| @@ -81,6 +81,18 @@ static void DeleteThread(void* thread) { |
| } |
| +OSThread* OSThread::CreateOSThread() { |
| + ASSERT(thread_list_lock_ != NULL); |
| + MutexLocker ml(thread_list_lock_); |
| + if (!creation_enabled_) { |
| + return NULL; |
| + } |
| + OSThread* os_thread = new OSThread(); |
| + AddThreadToList(os_thread); |
| + return os_thread; |
| +} |
| + |
| + |
| void OSThread::InitOnce() { |
| // Allocate the global OSThread lock. |
| ASSERT(thread_list_lock_ == NULL); |
| @@ -92,8 +104,12 @@ void OSThread::InitOnce() { |
| thread_key_ = CreateThreadLocal(DeleteThread); |
| ASSERT(thread_key_ != kUnsetThreadLocalKey); |
| + // Enable creation of OSThread structures in the VM. |
| + EnableOSThreadCreation(); |
| + |
| // Create a new OSThread strcture and set it as the TLS. |
| - OSThread* os_thread = new OSThread(); |
| + OSThread* os_thread = CreateOSThread(); |
| + ASSERT(os_thread != NULL); |
| OSThread::SetCurrent(os_thread); |
| os_thread->set_name("Dart_Initialize"); |
| } |
| @@ -116,9 +132,11 @@ void OSThread::Cleanup() { |
| OSThread* OSThread::CreateAndSetUnknownThread() { |
| ASSERT(OSThread::Current() == NULL); |
| - OSThread* os_thread = new OSThread(); |
| - OSThread::SetCurrent(os_thread); |
| - os_thread->set_name("Unknown"); |
| + OSThread* os_thread = CreateOSThread(); |
| + if (os_thread != NULL) { |
| + OSThread::SetCurrent(os_thread); |
| + os_thread->set_name("Unknown"); |
| + } |
| return os_thread; |
| } |
| @@ -141,6 +159,18 @@ bool OSThread::IsThreadInList(ThreadJoinId join_id) { |
| } |
| +void OSThread::DisableOSThreadCreation() { |
|
zra
2015/12/17 16:37:59
Where is this called?
siva
2015/12/17 18:19:13
Good point, forgot to add the call in Dart::Cleanu
|
| + MutexLocker ml(thread_list_lock_); |
| + creation_enabled_ = false; |
| +} |
| + |
| + |
| +void OSThread::EnableOSThreadCreation() { |
| + MutexLocker ml(thread_list_lock_); |
| + creation_enabled_ = true; |
| +} |
| + |
| + |
| OSThread* OSThread::GetOSThreadFromThread(Thread* thread) { |
| ASSERT(thread->os_thread() != NULL); |
| return thread->os_thread(); |
| @@ -150,8 +180,8 @@ OSThread* OSThread::GetOSThreadFromThread(Thread* thread) { |
| void OSThread::AddThreadToList(OSThread* thread) { |
|
zra
2015/12/17 16:37:59
AddThreadToListLocked?
siva
2015/12/17 18:19:13
Done.
|
| ASSERT(thread != NULL); |
| ASSERT(thread_list_lock_ != NULL); |
| - MutexLocker ml(thread_list_lock_); |
| - |
| + ASSERT(OSThread::thread_list_lock_->IsOwnedByCurrentThread()); |
| + ASSERT(creation_enabled_); |
| ASSERT(thread->thread_list_next_ == NULL); |
| #if defined(DEBUG) |
| @@ -172,6 +202,7 @@ void OSThread::AddThreadToList(OSThread* thread) { |
| void OSThread::RemoveThreadFromList(OSThread* thread) { |
| + bool final_thread = false; |
| { |
| ASSERT(thread != NULL); |
| ASSERT(thread_list_lock_ != NULL); |
| @@ -189,6 +220,7 @@ void OSThread::RemoveThreadFromList(OSThread* thread) { |
| previous->thread_list_next_ = current->thread_list_next_; |
| } |
| thread->thread_list_next_ = NULL; |
| + final_thread = !creation_enabled_ && (thread_list_head_ == NULL); |
|
Florian Schneider
2015/12/17 13:33:08
It seems DisableOSThreadCreation is never called i
siva
2015/12/17 18:19:13
Good catch, forgot to add the call in Dart::Cleanu
|
| break; |
| } |
| previous = current; |
| @@ -197,7 +229,7 @@ void OSThread::RemoveThreadFromList(OSThread* thread) { |
| } |
| // Check if this is the last thread. The last thread does a cleanup |
| // which removes the thread local key and the associated mutex. |
| - if (thread_list_head_ == NULL) { |
| + if (final_thread) { |
| Cleanup(); |
| } |
| } |