llvmpipe: Don't wait for already-terminated threads on Windows
authorJesse Natalie <jenatali@microsoft.com>
Sat, 4 Sep 2021 19:18:21 +0000 (12:18 -0700)
committerMarge Bot <eric+marge@anholt.net>
Tue, 7 Sep 2021 16:19:10 +0000 (16:19 +0000)
In the case of an app returning from main(), Windows will apparently terminate
other threads before invoking final cleanup on the main thread.

llvmpipe can't wait for threads to signal a semaphore if the thread is already
gone. Since we're already in a WIN32 special case, just call the Win32 API
to check if the thread is terminated or STILL_ALIVE.

Reviewed-by: Jose Fonseca <jfonseca@vmware.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12731>

src/gallium/drivers/llvmpipe/lp_rast.c

index f054f4c..f67fbda 100644 (file)
@@ -1366,7 +1366,12 @@ void lp_rast_destroy( struct lp_rasterizer *rast )
     * per https://bugs.freedesktop.org/show_bug.cgi?id=76252 */
    for (i = 0; i < rast->num_threads; i++) {
 #ifdef _WIN32
-      pipe_semaphore_wait(&rast->tasks[i].work_done);
+      /* Threads might already be dead - Windows apparently terminates other threads when
+       * returning from main.
+       */
+      DWORD exit_code = STILL_ACTIVE;
+      if (GetExitCodeThread(rast->threads[i], &exit_code) && exit_code == STILL_ACTIVE)
+         pipe_semaphore_wait(&rast->tasks[i].work_done);
 #else
       thrd_join(rast->threads[i], NULL);
 #endif