diff options
author | Ryan Prichard <rprichard@google.com> | 2019-04-23 20:55:52 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2019-04-23 20:55:52 +0000 |
commit | 53080db75a550f6b513b11e84881f592b128a1f5 (patch) | |
tree | aa5d90a5c88b3f2f82e2f8a670125cee86e160a4 | |
parent | 768eb27f0d09a779150c9d4fe1f0262601598a1d (diff) | |
parent | ea722a077963cff958d2dcd58f9ff4075a69df24 (diff) | |
download | android_bionic-53080db75a550f6b513b11e84881f592b128a1f5.tar.gz android_bionic-53080db75a550f6b513b11e84881f592b128a1f5.tar.bz2 android_bionic-53080db75a550f6b513b11e84881f592b128a1f5.zip |
Merge "PIMutexUnlock: load owner_tid in non-common case" into qt-dev
-rw-r--r-- | libc/bionic/pthread_mutex.cpp | 2 | ||||
-rw-r--r-- | tests/pthread_test.cpp | 18 |
2 files changed, 20 insertions, 0 deletions
diff --git a/libc/bionic/pthread_mutex.cpp b/libc/bionic/pthread_mutex.cpp index d9ddf1058..f92184e50 100644 --- a/libc/bionic/pthread_mutex.cpp +++ b/libc/bionic/pthread_mutex.cpp @@ -199,6 +199,8 @@ static int PIMutexUnlock(PIMutex& mutex) { memory_order_relaxed))) { return 0; } + } else { + old_owner = atomic_load_explicit(&mutex.owner_tid, memory_order_relaxed); } if (tid != (old_owner & FUTEX_TID_MASK)) { diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp index 7b64401db..0bf8e294b 100644 --- a/tests/pthread_test.cpp +++ b/tests/pthread_test.cpp @@ -1843,10 +1843,25 @@ struct PthreadMutex { DISALLOW_COPY_AND_ASSIGN(PthreadMutex); }; +static int UnlockFromAnotherThread(pthread_mutex_t* mutex) { + pthread_t thread; + pthread_create(&thread, nullptr, [](void* mutex_voidp) -> void* { + pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(mutex_voidp); + intptr_t result = pthread_mutex_unlock(mutex); + return reinterpret_cast<void*>(result); + }, mutex); + void* result; + EXPECT_EQ(0, pthread_join(thread, &result)); + return reinterpret_cast<intptr_t>(result); +}; + static void TestPthreadMutexLockNormal(int protocol) { PthreadMutex m(PTHREAD_MUTEX_NORMAL, protocol); ASSERT_EQ(0, pthread_mutex_lock(&m.lock)); + if (protocol == PTHREAD_PRIO_INHERIT) { + ASSERT_EQ(EPERM, UnlockFromAnotherThread(&m.lock)); + } ASSERT_EQ(0, pthread_mutex_unlock(&m.lock)); ASSERT_EQ(0, pthread_mutex_trylock(&m.lock)); ASSERT_EQ(EBUSY, pthread_mutex_trylock(&m.lock)); @@ -1857,6 +1872,7 @@ static void TestPthreadMutexLockErrorCheck(int protocol) { PthreadMutex m(PTHREAD_MUTEX_ERRORCHECK, protocol); ASSERT_EQ(0, pthread_mutex_lock(&m.lock)); + ASSERT_EQ(EPERM, UnlockFromAnotherThread(&m.lock)); ASSERT_EQ(EDEADLK, pthread_mutex_lock(&m.lock)); ASSERT_EQ(0, pthread_mutex_unlock(&m.lock)); ASSERT_EQ(0, pthread_mutex_trylock(&m.lock)); @@ -1873,7 +1889,9 @@ static void TestPthreadMutexLockRecursive(int protocol) { PthreadMutex m(PTHREAD_MUTEX_RECURSIVE, protocol); ASSERT_EQ(0, pthread_mutex_lock(&m.lock)); + ASSERT_EQ(EPERM, UnlockFromAnotherThread(&m.lock)); ASSERT_EQ(0, pthread_mutex_lock(&m.lock)); + ASSERT_EQ(EPERM, UnlockFromAnotherThread(&m.lock)); ASSERT_EQ(0, pthread_mutex_unlock(&m.lock)); ASSERT_EQ(0, pthread_mutex_unlock(&m.lock)); ASSERT_EQ(0, pthread_mutex_trylock(&m.lock)); |