Fix the pthread_join on self error case.
We should return EDEADLK, not deadlock the calling thread.
Change-Id: I1243483f709c11b2a60e41142725c54c7dbfcbc9
diff --git a/libc/bionic/pthread.c b/libc/bionic/pthread.c
index ac7c64e..c7612f7 100644
--- a/libc/bionic/pthread.c
+++ b/libc/bionic/pthread.c
@@ -633,14 +633,18 @@
int pthread_join(pthread_t thid, void ** ret_val)
{
pthread_internal_t* thread = (pthread_internal_t*)thid;
- int count;
+ if (thid == pthread_self()) {
+ return EDEADLK;
+ }
// check that the thread still exists and is not detached
pthread_mutex_lock(&gThreadListLock);
- for (thread = gThreadList; thread != NULL; thread = thread->next)
- if (thread == (pthread_internal_t*)thid)
+ for (thread = gThreadList; thread != NULL; thread = thread->next) {
+ if (thread == (pthread_internal_t*)thid) {
goto FoundIt;
+ }
+ }
pthread_mutex_unlock(&gThreadListLock);
return ESRCH;
@@ -658,7 +662,7 @@
*
* otherwise, we need to increment 'join-count' and wait to be signaled
*/
- count = thread->join_count;
+ int count = thread->join_count;
if (count >= 0) {
thread->join_count += 1;
pthread_cond_wait( &thread->join_cond, &gThreadListLock );
diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp
index 9a474c0..479c462 100644
--- a/tests/pthread_test.cpp
+++ b/tests/pthread_test.cpp
@@ -80,3 +80,8 @@
ASSERT_EQ(0, pthread_join(t2, &join_result));
ASSERT_EQ(EINVAL, reinterpret_cast<int>(join_result));
}
+
+TEST(pthread, pthread_join_self) {
+ void* result;
+ ASSERT_EQ(EDEADLK, pthread_join(pthread_self(), &result));
+}