Avoid abort when calling pthread_mutex_destroy more than once.
Bug: http://b/72878088
Test: run bionic-unit-tests.
Change-Id: I0c3a6c5a625d187d5f32ec8c821cfdd5e807a671
diff --git a/libc/bionic/pthread_mutex.cpp b/libc/bionic/pthread_mutex.cpp
index e5f2a31..f1f7294 100644
--- a/libc/bionic/pthread_mutex.cpp
+++ b/libc/bionic/pthread_mutex.cpp
@@ -943,11 +943,16 @@
int pthread_mutex_destroy(pthread_mutex_t* mutex_interface) {
pthread_mutex_internal_t* mutex = __get_internal_mutex(mutex_interface);
uint16_t old_state = atomic_load_explicit(&mutex->state, memory_order_relaxed);
+ if (old_state == 0xffff) {
+ // The mutex has been destroyed.
+ return EBUSY;
+ }
uint16_t mtype = (old_state & MUTEX_TYPE_MASK);
if (mtype == MUTEX_TYPE_BITS_WITH_PI) {
int result = PIMutexDestroy(mutex->ToPIMutex());
if (result == 0) {
mutex->FreePIMutex();
+ atomic_store(&mutex->state, 0xffff);
}
return result;
}
diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp
index 40059d0..8ac5223 100644
--- a/tests/pthread_test.cpp
+++ b/tests/pthread_test.cpp
@@ -1672,6 +1672,7 @@
void destroy() {
ASSERT_EQ(0, pthread_mutex_destroy(&lock));
+ ASSERT_EQ(EBUSY, pthread_mutex_destroy(&lock));
}
DISALLOW_COPY_AND_ASSIGN(PthreadMutex);