]> granicus.if.org Git - gc/commitdiff
Reduce a time period between GetExitCodeThread and SuspendThread (Win32)
authorIvan Maidanski <ivmai@mail.ru>
Thu, 3 Oct 2019 21:38:28 +0000 (00:38 +0300)
committerIvan Maidanski <ivmai@mail.ru>
Thu, 10 Oct 2019 21:49:22 +0000 (00:49 +0300)
(a cherry-pick of commit 5d7cf8de from 'release-7_4')

* win32_threads.c [!MSWINCE && MPROTECT_VDB] (GC_suspend): Move
AO_test_and_set_acquire() call to be before GetExitCodeThread();
call AO_CLEAR() immediately if GetExitCodeThread() failed.

win32_threads.c

index a717a1d1859da70e4d8252743d0f750c6bbf6cd4..4892a7e19ee1492961ac02b5693fa26671f51b2d 100644 (file)
@@ -1113,21 +1113,8 @@ STATIC void GC_suspend(GC_thread t)
     /* appears there's a race here.                                     */
     DWORD exitCode;
 # endif
+
   UNPROTECT_THREAD(t);
-# ifndef MSWINCE
-    if (GetExitCodeThread(t -> handle, &exitCode) &&
-        exitCode != STILL_ACTIVE) {
-#     ifdef GC_PTHREADS
-        t -> stack_base = 0; /* prevent stack from being pushed */
-#     else
-        /* this breaks pthread_join on Cygwin, which is guaranteed to  */
-        /* only see user pthreads                                      */
-        GC_ASSERT(GC_win32_dll_threads);
-        GC_delete_gc_thread(t);
-#     endif
-      return;
-    }
-# endif
 # if defined(MPROTECT_VDB)
     /* Acquire the spin lock we use to update dirty bits.       */
     /* Threads shouldn't get stopped holding it.  But we may    */
@@ -1142,9 +1129,24 @@ STATIC void GC_suspend(GC_thread t)
     while (SuspendThread(THREAD_HANDLE(t)) == (DWORD)-1)
       Sleep(10); /* in millis */
 # else
+    if (GetExitCodeThread(t -> handle, &exitCode)
+        && exitCode != STILL_ACTIVE) {
+#     ifdef MPROTECT_VDB
+        AO_CLEAR(&GC_fault_handler_lock);
+#     endif
+#     ifdef GC_PTHREADS
+        t -> stack_base = 0; /* prevent stack from being pushed */
+#     else
+        /* this breaks pthread_join on Cygwin, which is guaranteed to  */
+        /* only see user pthreads                                      */
+        GC_ASSERT(GC_win32_dll_threads);
+        GC_delete_gc_thread(t);
+#     endif
+      return;
+    }
     if (SuspendThread(t -> handle) == (DWORD)-1)
       ABORT("SuspendThread failed");
-# endif /* !MSWINCE */
+# endif
   t -> suspended = (unsigned char)TRUE;
 # if defined(MPROTECT_VDB)
     AO_CLEAR(&GC_fault_handler_lock);