Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 3d53df5

Browse files
mkustermanncommit-bot@chromium.org
authored andcommitted
Revert "[vm] Call OSThread::Cleanup() during VM shutdown (as with all other Init/Cleanup functions)"
See b/157883819: Custom embedder doesn't correctly join threads that interacted with Dart API, which causes us to hit the newly added RELEASE_ASSERT. This reverts commit ea4b175. Change-Id: I9fec45196646f67ae46efccc2f83a43e8941a626 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/149592 Reviewed-by: David Morgan <[email protected]> Commit-Queue: Martin Kustermann <[email protected]>
1 parent 6f66f82 commit 3d53df5

File tree

5 files changed

+49
-39
lines changed

5 files changed

+49
-39
lines changed

runtime/vm/dart.cc

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -617,7 +617,12 @@ char* Dart::Cleanup() {
617617
Timeline::Cleanup();
618618
#endif
619619
Zone::Cleanup();
620-
OSThread::Cleanup();
620+
// Delete the current thread's TLS and set it's TLS to null.
621+
// If it is the last thread then the destructor would call
622+
// OSThread::Cleanup.
623+
OSThread* os_thread = OSThread::Current();
624+
OSThread::SetCurrent(NULL);
625+
delete os_thread;
621626
if (FLAG_trace_shutdown) {
622627
OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Deleted os_thread\n",
623628
UptimeMillis());

runtime/vm/malloc_hooks_test.cc

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,10 @@ static void MallocHookTestBufferInitializer(volatile char* buffer,
2525
}
2626
}
2727

28-
// Only to be used in UNIT_TEST_CASE which runs without active VM.
29-
class OSThreadSupport : public ValueObject {
30-
public:
31-
OSThreadSupport() { OSThread::Init(); }
32-
33-
~OSThreadSupport() { OSThread::Cleanup(); }
34-
};
35-
3628
class EnableMallocHooksScope : public ValueObject {
3729
public:
3830
EnableMallocHooksScope() {
31+
OSThread::Current(); // Ensure not allocated during test.
3932
saved_enable_malloc_hooks_ = FLAG_profiler_native_memory;
4033
FLAG_profiler_native_memory = true;
4134
MallocHooks::Init();
@@ -73,7 +66,6 @@ class EnableMallocHooksAndStacksScope : public EnableMallocHooksScope {
7366
};
7467

7568
UNIT_TEST_CASE(BasicMallocHookTest) {
76-
OSThreadSupport os_thread_support;
7769
EnableMallocHooksScope scope;
7870

7971
EXPECT_EQ(0L, MallocHooks::allocation_count());
@@ -92,7 +84,6 @@ UNIT_TEST_CASE(BasicMallocHookTest) {
9284
}
9385

9486
UNIT_TEST_CASE(FreeUnseenMemoryMallocHookTest) {
95-
OSThreadSupport os_thread_support;
9687
EnableMallocHooksScope scope;
9788

9889
const intptr_t pre_hook_buffer_size = 3;

runtime/vm/os_thread.cc

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -134,18 +134,21 @@ bool OSThread::ThreadInterruptsEnabled() {
134134
return thread_interrupt_disabled_ == 0;
135135
}
136136

137-
static void DeleteOSThreadTLS(void* thread) {
137+
static void DeleteThread(void* thread) {
138138
delete reinterpret_cast<OSThread*>(thread);
139139
}
140140

141141
void OSThread::Init() {
142142
// Allocate the global OSThread lock.
143-
ASSERT(thread_list_lock_ == nullptr);
144-
thread_list_lock_ = new Mutex();
143+
if (thread_list_lock_ == NULL) {
144+
thread_list_lock_ = new Mutex();
145+
}
146+
ASSERT(thread_list_lock_ != NULL);
145147

146148
// Create the thread local key.
147-
ASSERT(thread_key_ == kUnsetThreadLocalKey);
148-
thread_key_ = CreateThreadLocal(DeleteOSThreadTLS);
149+
if (thread_key_ == kUnsetThreadLocalKey) {
150+
thread_key_ = CreateThreadLocal(DeleteThread);
151+
}
149152
ASSERT(thread_key_ != kUnsetThreadLocalKey);
150153

151154
// Enable creation of OSThread structures in the VM.
@@ -159,25 +162,21 @@ void OSThread::Init() {
159162
}
160163

161164
void OSThread::Cleanup() {
162-
// Delete the current thread's TLS (if any).
163-
OSThread* os_thread = OSThread::Current();
164-
OSThread::SetCurrent(nullptr);
165-
delete os_thread;
166-
167-
// At this point all OSThread structures should have been deleted.
168-
// If not we have a bug in the code where a thread is not correctly joined
169-
// before `Dart::Cleanup()`.
170-
RELEASE_ASSERT(OSThread::thread_list_head_ == nullptr);
171-
172-
// Delete the thread local key.
173-
ASSERT(thread_key_ != kUnsetThreadLocalKey);
174-
DeleteThreadLocal(thread_key_);
175-
thread_key_ = kUnsetThreadLocalKey;
176-
177-
// Delete the global OSThread lock.
178-
ASSERT(thread_list_lock_ != nullptr);
179-
delete thread_list_lock_;
180-
thread_list_lock_ = nullptr;
165+
// We cannot delete the thread local key and thread list lock, yet.
166+
// See the note on thread_list_lock_ in os_thread.h.
167+
#if 0
168+
if (thread_list_lock_ != NULL) {
169+
// Delete the thread local key.
170+
ASSERT(thread_key_ != kUnsetThreadLocalKey);
171+
DeleteThreadLocal(thread_key_);
172+
thread_key_ = kUnsetThreadLocalKey;
173+
174+
// Delete the global OSThread lock.
175+
ASSERT(thread_list_lock_ != NULL);
176+
delete thread_list_lock_;
177+
thread_list_lock_ = NULL;
178+
}
179+
#endif
181180
}
182181

183182
OSThread* OSThread::CreateAndSetUnknownThread() {
@@ -246,6 +245,7 @@ void OSThread::AddThreadToListLocked(OSThread* thread) {
246245
}
247246

248247
void OSThread::RemoveThreadFromList(OSThread* thread) {
248+
bool final_thread = false;
249249
{
250250
ASSERT(thread != NULL);
251251
ASSERT(thread_list_lock_ != NULL);
@@ -263,12 +263,18 @@ void OSThread::RemoveThreadFromList(OSThread* thread) {
263263
previous->thread_list_next_ = current->thread_list_next_;
264264
}
265265
thread->thread_list_next_ = NULL;
266+
final_thread = !creation_enabled_ && (thread_list_head_ == NULL);
266267
break;
267268
}
268269
previous = current;
269270
current = current->thread_list_next_;
270271
}
271272
}
273+
// Check if this is the last thread. The last thread does a cleanup
274+
// which removes the thread local key and the associated mutex.
275+
if (final_thread) {
276+
Cleanup();
277+
}
272278
}
273279

274280
void OSThread::SetCurrentTLS(BaseThread* value) {

runtime/vm/os_thread.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,6 @@ class OSThread : public BaseThread {
229229

230230
// Called at VM startup and shutdown.
231231
static void Init();
232-
static void Cleanup();
233232

234233
static bool IsThreadInList(ThreadId id);
235234

@@ -256,6 +255,7 @@ class OSThread : public BaseThread {
256255
ThreadState* thread() const { return thread_; }
257256
void set_thread(ThreadState* value) { thread_ = value; }
258257

258+
static void Cleanup();
259259
#ifdef SUPPORT_TIMELINE
260260
static ThreadId GetCurrentThreadTraceId();
261261
#endif // PRODUCT
@@ -299,8 +299,11 @@ class OSThread : public BaseThread {
299299
// protected and should only be read/written by the OSThread itself.
300300
void* owning_thread_pool_worker_ = nullptr;
301301

302-
// [thread_list_lock_] cannot have a static lifetime because the order in
303-
// which destructors run is undefined.
302+
// thread_list_lock_ cannot have a static lifetime because the order in which
303+
// destructors run is undefined. At the moment this lock cannot be deleted
304+
// either since otherwise, if a thread only begins to run after we have
305+
// started to run TLS destructors for a call to exit(), there will be a race
306+
// on its deletion in CreateOSThread().
304307
static Mutex* thread_list_lock_;
305308
static OSThread* thread_list_head_;
306309
static bool creation_enabled_;

runtime/vm/thread_pool_test.cc

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,12 @@ DECLARE_FLAG(int, worker_timeout_millis);
1919
UNIT_TEST_CASE(name) { \
2020
OSThread::Init(); \
2121
name##helper(); \
22-
OSThread::Cleanup(); \
22+
/* Delete the current thread's TLS and set it's TLS to null. */ \
23+
/* If it is the last thread then the destructor would call */ \
24+
/* OSThread::Cleanup. */ \
25+
OSThread* os_thread = OSThread::Current(); \
26+
OSThread::SetCurrent(nullptr); \
27+
delete os_thread; \
2328
} \
2429
void name##helper()
2530

0 commit comments

Comments
 (0)