diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp index e260e97f8..ce430097e 100644 --- a/libc/bionic/pthread_create.cpp +++ b/libc/bionic/pthread_create.cpp @@ -193,8 +193,7 @@ static int __pthread_start(void* arg) { // notify gdb about this thread before we start doing anything. // This also provides the memory barrier needed to ensure that all memory // accesses previously made by the creating thread are visible to us. - pthread_mutex_lock(&thread->startup_handshake_mutex); - pthread_mutex_destroy(&thread->startup_handshake_mutex); + thread->startup_handshake_lock.lock(); __init_alternate_signal_stack(thread); @@ -233,14 +232,14 @@ int pthread_create(pthread_t* thread_out, pthread_attr_t const* attr, return result; } - // Create a mutex for the thread in TLS to wait on once it starts so we can keep + // Create a lock for the thread to wait on once it starts so we can keep // it from doing anything until after we notify the debugger about it // // This also provides the memory barrier we need to ensure that all // memory accesses previously performed by this thread are visible to // the new thread. - pthread_mutex_init(&thread->startup_handshake_mutex, NULL); - pthread_mutex_lock(&thread->startup_handshake_mutex); + thread->startup_handshake_lock.init(false); + thread->startup_handshake_lock.lock(); thread->start_routine = start_routine; thread->start_routine_arg = arg; @@ -263,7 +262,7 @@ int pthread_create(pthread_t* thread_out, pthread_attr_t const* attr, // We don't have to unlock the mutex at all because clone(2) failed so there's no child waiting to // be unblocked, but we're about to unmap the memory the mutex is stored in, so this serves as a // reminder that you can't rewrite this function to use a ScopedPthreadMutexLocker. - pthread_mutex_unlock(&thread->startup_handshake_mutex); + thread->startup_handshake_lock.unlock(); if (thread->mmap_size != 0) { munmap(thread->attr.stack_base, thread->mmap_size); } @@ -278,13 +277,13 @@ int pthread_create(pthread_t* thread_out, pthread_attr_t const* attr, atomic_store(&thread->join_state, THREAD_DETACHED); __pthread_internal_add(thread); thread->start_routine = __do_nothing; - pthread_mutex_unlock(&thread->startup_handshake_mutex); + thread->startup_handshake_lock.unlock(); return init_errno; } // Publish the pthread_t and unlock the mutex to let the new thread start running. *thread_out = __pthread_internal_add(thread); - pthread_mutex_unlock(&thread->startup_handshake_mutex); + thread->startup_handshake_lock.unlock(); return 0; } diff --git a/libc/bionic/pthread_internal.h b/libc/bionic/pthread_internal.h index 6a39a214a..d5d62a787 100644 --- a/libc/bionic/pthread_internal.h +++ b/libc/bionic/pthread_internal.h @@ -31,6 +31,7 @@ #include #include +#include "private/bionic_lock.h" #include "private/bionic_tls.h" /* Has the thread been detached by a pthread_join or pthread_detach call? */ @@ -89,7 +90,7 @@ struct pthread_internal_t { void* alternate_signal_stack; - pthread_mutex_t startup_handshake_mutex; + Lock startup_handshake_lock; size_t mmap_size; diff --git a/libc/private/bionic_lock.h b/libc/private/bionic_lock.h index 6a0fd06ad..a36d1edd3 100644 --- a/libc/private/bionic_lock.h +++ b/libc/private/bionic_lock.h @@ -31,6 +31,8 @@ #include #include "private/bionic_futex.h" +// Lock is used in places like pthread_rwlock_t, which can be initialized without calling +// an initialization function. So make sure Lock can be initialized by setting its memory to 0. class Lock { private: enum LockState { @@ -42,10 +44,6 @@ class Lock { bool process_shared; public: - Lock(bool process_shared = false) { - init(process_shared); - } - void init(bool process_shared) { atomic_init(&state, Unlocked); this->process_shared = process_shared;