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

Unified Diff: runtime/vm/thread.cc

Issue 1293253005: Completely remove InterruptableThreadState and Fix ThreadRegistry leak (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 4 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
« no previous file with comments | « runtime/vm/thread.h ('k') | runtime/vm/thread_interrupter.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/thread.cc
diff --git a/runtime/vm/thread.cc b/runtime/vm/thread.cc
index fdd3272e340ecf1029b9a87c5c067bbcd3b80440..260f59088ae169ec397713235d46287c90f0e43b 100644
--- a/runtime/vm/thread.cc
+++ b/runtime/vm/thread.cc
@@ -21,6 +21,24 @@ namespace dart {
ThreadLocalKey Thread::thread_key_ = OSThread::kUnsetThreadLocalKey;
+// Remove |thread| from each isolate's thread registry.
+class ThreadPruner : public IsolateVisitor {
+ public:
+ explicit ThreadPruner(Thread* thread)
+ : thread_(thread) {
+ ASSERT(thread_ != NULL);
+ }
+
+ void VisitIsolate(Isolate* isolate) {
+ ThreadRegistry* registry = isolate->thread_registry();
+ ASSERT(registry != NULL);
+ registry->PruneThread(thread_);
+ }
+ private:
+ Thread* thread_;
+};
+
+
static void DeleteThread(void* thread) {
delete reinterpret_cast<Thread*>(thread);
}
@@ -29,6 +47,9 @@ static void DeleteThread(void* thread) {
Thread::~Thread() {
// We should cleanly exit any isolate before destruction.
ASSERT(isolate_ == NULL);
+ // Clear |this| from all isolate's thread registry.
+ ThreadPruner pruner(this);
+ Isolate::VisitIsolates(&pruner);
}
@@ -37,8 +58,11 @@ void Thread::InitOnceBeforeIsolate() {
thread_key_ = OSThread::CreateThreadLocal(DeleteThread);
ASSERT(thread_key_ != OSThread::kUnsetThreadLocalKey);
ASSERT(Thread::Current() == NULL);
- // Postpone initialization of VM constants for this first thread.
- SetCurrent(new Thread(false));
+ // Allocate a new Thread and postpone initialization of VM constants for
+ // this first thread.
+ Thread* thread = new Thread(false);
+ // Verify that current thread was set.
+ ASSERT(Thread::Current() == thread);
}
@@ -57,7 +81,10 @@ void Thread::SetCurrent(Thread* current) {
void Thread::EnsureInit() {
if (Thread::Current() == NULL) {
- SetCurrent(new Thread());
+ // Allocate a new Thread.
+ Thread* thread = new Thread();
+ // Verify that current thread was set.
+ ASSERT(Thread::Current() == thread);
}
}
@@ -74,7 +101,8 @@ void Thread::CleanUp() {
Thread::Thread(bool init_vm_constants)
- : isolate_(NULL),
+ : id_(OSThread::GetCurrentThreadId()),
+ isolate_(NULL),
store_buffer_block_(NULL) {
ClearState();
#define DEFAULT_INIT(type_name, member_name, init_expr, default_init_value) \
@@ -84,6 +112,7 @@ CACHED_CONSTANTS_LIST(DEFAULT_INIT)
if (init_vm_constants) {
InitVMConstants();
}
+ SetCurrent(this);
}
@@ -131,15 +160,6 @@ void Thread::EnterIsolate(Isolate* isolate) {
ASSERT(isolate->heap() != NULL);
thread->heap_ = isolate->heap();
thread->Schedule(isolate);
- ASSERT(thread->thread_state() == NULL);
- InterruptableThreadState* thread_state =
- ThreadInterrupter::GetCurrentThreadState();
-#if defined(DEBUG)
- thread->set_thread_state(NULL); // Exclude thread itself from the dupe check.
- Isolate::CheckForDuplicateThreadState(thread_state);
- thread->set_thread_state(thread_state);
-#endif
- ASSERT(thread_state != NULL);
// TODO(koda): Migrate profiler interface to use Thread.
Profiler::BeginExecution(isolate);
}
@@ -151,7 +171,6 @@ void Thread::ExitIsolate() {
if (thread == NULL || thread->isolate() == NULL) return;
Isolate* isolate = thread->isolate();
Profiler::EndExecution(isolate);
- thread->set_thread_state(NULL);
thread->Unschedule();
// TODO(koda): Move store_buffer_block_ into State.
thread->StoreBufferRelease();
@@ -259,6 +278,32 @@ void Thread::set_cha(CHA* value) {
}
+void Thread::SetThreadInterrupter(ThreadInterruptCallback callback,
+ void* data) {
+ ASSERT(Thread::Current() == this);
+ thread_interrupt_callback_ = callback;
+ thread_interrupt_data_ = data;
+}
+
+
+bool Thread::IsThreadInterrupterEnabled(ThreadInterruptCallback* callback,
+ void** data) const {
+#if defined(TARGET_OS_WINDOWS)
+ // On Windows we expect this to be called from the thread interrupter thread.
+ ASSERT(id() != OSThread::GetCurrentThreadId());
+#else
+ // On posix platforms, we expect this to be called from signal handler.
+ ASSERT(id() == OSThread::GetCurrentThreadId());
+#endif
+ ASSERT(callback != NULL);
+ ASSERT(data != NULL);
+ *callback = thread_interrupt_callback_;
+ *data = thread_interrupt_data_;
+ return (*callback != NULL) &&
+ (*data != NULL);
+}
+
+
bool Thread::CanLoadFromThread(const Object& object) {
#define CHECK_OBJECT(type_name, member_name, expr, default_init_value) \
if (object.raw() == expr) return true;
« no previous file with comments | « runtime/vm/thread.h ('k') | runtime/vm/thread_interrupter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698