am fd9e20d1
: Merge "Fix pthread_detach for already-exited threads."
* commit 'fd9e20d10f946334955ca199b0178580d284e89f': Fix pthread_detach for already-exited threads.
This commit is contained in:
commit
00b522ad9e
@ -44,6 +44,12 @@ int pthread_detach(pthread_t t) {
|
|||||||
return 0; // Already being joined; silently do nothing, like glibc.
|
return 0; // Already being joined; silently do nothing, like glibc.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (thread->tid == 0) {
|
||||||
|
// Already exited; clean up.
|
||||||
|
_pthread_internal_remove_locked(thread.get());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
thread->attr.flags |= PTHREAD_ATTR_FLAG_DETACHED;
|
thread->attr.flags |= PTHREAD_ATTR_FLAG_DETACHED;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <malloc.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
@ -350,6 +351,35 @@ TEST(pthread, pthread_detach__no_such_thread) {
|
|||||||
ASSERT_EQ(ESRCH, pthread_detach(dead_thread));
|
ASSERT_EQ(ESRCH, pthread_detach(dead_thread));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(pthread, pthread_detach__leak) {
|
||||||
|
size_t initial_bytes = mallinfo().uordblks;
|
||||||
|
|
||||||
|
pthread_attr_t attr;
|
||||||
|
ASSERT_EQ(0, pthread_attr_init(&attr));
|
||||||
|
ASSERT_EQ(0, pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE));
|
||||||
|
|
||||||
|
std::vector<pthread_t> threads;
|
||||||
|
for (size_t i = 0; i < 32; ++i) {
|
||||||
|
pthread_t t;
|
||||||
|
ASSERT_EQ(0, pthread_create(&t, &attr, IdFn, NULL));
|
||||||
|
threads.push_back(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
sleep(1);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < 32; ++i) {
|
||||||
|
ASSERT_EQ(0, pthread_detach(threads[i])) << i;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t final_bytes = mallinfo().uordblks;
|
||||||
|
|
||||||
|
int leaked_bytes = (final_bytes - initial_bytes);
|
||||||
|
|
||||||
|
// User code (like this test) doesn't know how large pthread_internal_t is.
|
||||||
|
// We can be pretty sure it's more than 128 bytes.
|
||||||
|
ASSERT_LT(leaked_bytes, 32 /*threads*/ * 128 /*bytes*/);
|
||||||
|
}
|
||||||
|
|
||||||
TEST(pthread, pthread_getcpuclockid__clock_gettime) {
|
TEST(pthread, pthread_getcpuclockid__clock_gettime) {
|
||||||
pthread_t t;
|
pthread_t t;
|
||||||
ASSERT_EQ(0, pthread_create(&t, NULL, SleepFn, reinterpret_cast<void*>(5)));
|
ASSERT_EQ(0, pthread_create(&t, NULL, SleepFn, reinterpret_cast<void*>(5)));
|
||||||
|
Loading…
Reference in New Issue
Block a user