Fix thread id leaks in subthread_create and threadkey_test
authorIvan Maidanski <ivmai@mail.ru>
Tue, 19 Sep 2017 22:23:43 +0000 (01:23 +0300)
committerIvan Maidanski <ivmai@mail.ru>
Tue, 19 Sep 2017 22:23:43 +0000 (01:23 +0300)
* 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
tests/test.c
tests/threadkey_test.c

index 6fd889e..d83a76a 100644 (file)
@@ -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,
index d002e3f..c8b9cec 100644 (file)
@@ -2230,7 +2230,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
index 859f53f..b08a0a9 100644 (file)
@@ -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);
       }
     }