Chromium Code Reviews| Index: runtime/vm/thread.cc |
| diff --git a/runtime/vm/thread.cc b/runtime/vm/thread.cc |
| index 56c25af41b5d8144a628c5dd909f72cf0e734876..d766ef7cf7c05241d99bc11bf436d60f3a77fd9b 100644 |
| --- a/runtime/vm/thread.cc |
| +++ b/runtime/vm/thread.cc |
| @@ -23,7 +23,8 @@ namespace dart { |
| // The single thread local key which stores all the thread local data |
| // for a thread. |
| ThreadLocalKey Thread::thread_key_ = OSThread::kUnsetThreadLocalKey; |
| - |
| +Thread* Thread::thread_list_head_ = NULL; |
| +Mutex Thread::thread_list_lock_; |
| // Remove |thread| from each isolate's thread registry. |
| class ThreadPruner : public IsolateVisitor { |
| @@ -43,6 +44,64 @@ class ThreadPruner : public IsolateVisitor { |
| }; |
| +void Thread::AddThreadToList(Thread* thread) { |
| + ASSERT(thread != NULL); |
| + MutexLocker ml(&thread_list_lock_); |
| + ASSERT(thread->thread_list_next_ == NULL); |
| +#if defined(DEBUG) |
| + { |
| + // Ensure that we aren't already in the list. |
| + Thread* current = thread_list_head_; |
| + while (current != NULL) { |
| + ASSERT(current != thread); |
| + current = current->thread_list_next_; |
| + } |
| + } |
| +#endif |
| + // Insert at head of list. |
| + thread->thread_list_next_ = thread_list_head_; |
| + thread_list_head_ = thread; |
| +} |
| + |
| + |
| +void Thread::RemoveThreadFromList(Thread* thread) { |
| + ASSERT(thread != NULL); |
| + MutexLocker ml(&thread_list_lock_); |
| + |
| + // Handle case where |thread| is head of list. |
| + if (thread_list_head_ == thread) { |
| + thread_list_head_ = thread->thread_list_next_; |
| + thread->thread_list_next_ = NULL; |
| + return; |
| + } |
| + |
| + Thread* current = thread_list_head_; |
| + Thread* previous = NULL; |
| + |
| +#if defined(DEBUG) |
| + bool found_in_list = false; |
| +#endif |
| + |
| + // Scan across list and remove |thread|. |
| + while (current != NULL) { |
| + previous = current; |
| + current = current->thread_list_next_; |
| + if (current == thread) { |
| + // We found |thread|, remove from list. |
| + previous->thread_list_next_ = current->thread_list_next_; |
| +#if defined(DEBUG) |
| + found_in_list = true; |
| +#endif |
|
siva
2015/10/12 23:03:14
missing 'break;' here?
Maybe you could restructu
Cutch
2015/10/13 16:41:23
Done.
|
| + } |
| + } |
| + |
| +#if defined(DEBUG) |
| + ASSERT(found_in_list); |
| +#endif |
| + thread->thread_list_next_ = NULL; |
| +} |
| + |
| + |
| static void DeleteThread(void* thread) { |
| delete reinterpret_cast<Thread*>(thread); |
| } |
| @@ -56,6 +115,7 @@ Thread::~Thread() { |
| Isolate::VisitIsolates(&pruner); |
| delete log_; |
| log_ = NULL; |
| + RemoveThreadFromList(this); |
| } |
| @@ -127,7 +187,8 @@ Thread::Thread(bool init_vm_constants) |
| vm_tag_(0), |
| REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_INITIALIZERS) |
| REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_SCOPE_INIT) |
| - reusable_handles_() { |
| + reusable_handles_(), |
| + thread_list_next_(NULL) { |
| ClearState(); |
| #define DEFAULT_INIT(type_name, member_name, init_expr, default_init_value) \ |
| @@ -149,6 +210,7 @@ LEAF_RUNTIME_ENTRY_LIST(DEFAULT_INIT) |
| InitVMConstants(); |
| } |
| SetCurrent(this); |
| + AddThreadToList(this); |
| } |
| @@ -431,4 +493,30 @@ LEAF_RUNTIME_ENTRY_LIST(COMPUTE_OFFSET) |
| return -1; |
| } |
| + |
| +ThreadIterator::ThreadIterator() { |
| + // Lock the thread list while iterating. |
| + Thread::thread_list_lock_.Lock(); |
| + next_ = Thread::thread_list_head_; |
| +} |
| + |
| + |
| +ThreadIterator::~ThreadIterator() { |
| + // Unlock the thread list when done. |
| + Thread::thread_list_lock_.Unlock(); |
| +} |
| + |
| + |
| +bool ThreadIterator::HasNext() { |
|
siva
2015/10/12 23:03:14
ASSERT(Thread::thread_list_lock_->IsOwnedByCurrent
Cutch
2015/10/13 16:41:23
Done.
|
| + return next_ != NULL; |
| +} |
| + |
| + |
| +Thread* ThreadIterator::Next() { |
|
siva
2015/10/12 23:03:14
ASSERT(Thread::thread_list_lock_->IsOwnedByCurrent
Cutch
2015/10/13 16:41:23
Done.
|
| + Thread* current = next_; |
| + next_ = next_->thread_list_next_; |
| + return current; |
| +} |
| + |
| + |
| } // namespace dart |