From 7574e33a0b93754c875fd7d6021111cb0187c157 Mon Sep 17 00:00:00 2001 From: Ivan Maidanski Date: Wed, 20 Sep 2017 01:23:43 +0300 Subject: [PATCH] Fix thread id leaks in subthread_create and threadkey_test * tests/subthread_create.c [GC_PTHREADS] (entry): Call pthread_detach for the created thread. * tests/threadkey_test.c (main): Likewise. * tests/test.c [GC_PTHREADS && CPPCHECK] (main): Remove UNTESTED(GC_pthread_detach). * tests/threadkey_test.c (on_thread_exit_inner): New local variable attr; call pthread_attr_init and pthread_attr_setdetachstate; pass attr to GC_pthread_create; call pthread_attr_destroy. --- tests/subthread_create.c | 10 +++++++++- tests/test.c | 1 - tests/threadkey_test.c | 22 ++++++++++++++++------ 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/tests/subthread_create.c b/tests/subthread_create.c index 46021b23..67573f3a 100644 --- a/tests/subthread_create.c +++ b/tests/subthread_create.c @@ -59,15 +59,23 @@ volatile AO_t thread_ended_cnt = 0; # ifdef GC_PTHREADS int err; pthread_t th; + err = pthread_create(&th, NULL, entry, (void *)my_depth); - if (err) { + if (err != 0) { fprintf(stderr, "Thread #%d creation failed: %s\n", thread_num, strerror(err)); exit(2); } + err = pthread_detach(th); + if (err != 0) { + fprintf(stderr, "Thread #%d detach failed: %s\n", thread_num, + strerror(err)); + exit(2); + } # else HANDLE th; DWORD thread_id; + th = CreateThread(NULL, 0, entry, (LPVOID)my_depth, 0, &thread_id); if (th == NULL) { fprintf(stderr, "Thread #%d creation failed: %d\n", thread_num, diff --git a/tests/test.c b/tests/test.c index 0c9e1891..a4bfc856 100644 --- a/tests/test.c +++ b/tests/test.c @@ -2246,7 +2246,6 @@ int main(void) (void)fflush(stdout); (void)pthread_attr_destroy(&attr); # if defined(CPPCHECK) - UNTESTED(GC_pthread_detach); UNTESTED(GC_set_suspend_signal); UNTESTED(GC_set_thr_restart_signal); # ifndef GC_NO_DLOPEN diff --git a/tests/threadkey_test.c b/tests/threadkey_test.c index 859f53fd..b08a0a94 100644 --- a/tests/threadkey_test.c +++ b/tests/threadkey_test.c @@ -55,8 +55,15 @@ void * GC_CALLBACK on_thread_exit_inner (struct GC_stack_base * sb, void * arg) pthread_t t; int creation_res; /* Used to suppress a warning about */ /* unchecked pthread_create() result. */ + pthread_attr_t attr; - creation_res = GC_pthread_create (&t, NULL, entry, NULL); + if (pthread_attr_init(&attr) != 0 + || pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0) { + fprintf(stderr, "Thread attribute init or setdetachstate failed\n"); + exit(2); + } + creation_res = GC_pthread_create(&t, &attr, entry, NULL); + (void)pthread_attr_destroy(&attr); if (res == GC_SUCCESS) GC_unregister_my_thread (); @@ -89,12 +96,15 @@ int main (void) # endif for (i = 0; i < LIMIT; i++) { pthread_t t; - void *res; - if (GC_pthread_create (&t, NULL, entry, NULL) == 0 - && (i & 1) != 0) { - int code = GC_pthread_join(t, &res); + + if (GC_pthread_create(&t, NULL, entry, NULL) == 0) { + void *res; + int code = (i & 1) != 0 ? GC_pthread_join(t, &res) + : GC_pthread_detach(t); + if (code != 0) { - fprintf(stderr, "Thread join failed %d\n", code); + fprintf(stderr, "Thread %s failed %d\n", + (i & 1) != 0 ? "join" : "detach", code); exit(2); } } -- 2.40.0