summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/llvmpipe
diff options
context:
space:
mode:
authorJosé Fonseca <[email protected]>2014-11-07 16:15:43 +0000
committerJosé Fonseca <[email protected]>2014-11-07 21:00:06 +0000
commit706ad3b649e6a75fdac9dc9acc3caa9e6067b853 (patch)
tree3ba95737f1e3413ec6e24f2c7a595661d4a9cc68 /src/gallium/drivers/llvmpipe
parentedb7b1c56622bf4e68cd363c06b6443d07900b7a (diff)
llvmpipe: Avoid deadlock when unloading opengl32.dll
On Windows, DllMain calls and thread creation/destruction are serialized, so when llvmpipe is destroyed from DllMain waiting for the rasterizer threads to finish will deadlock. So, instead of waiting for rasterizer threads to have finished, simply wait for the rasterizer threads to notify they are just about to finish. Verified with this very simple program: #include <windows.h> int main() { HMODULE hModule = LoadLibraryA("opengl32.dll"); FreeLibrary(hModule); } Fixes https://bugs.freedesktop.org/show_bug.cgi?id=76252 Reviewed-by: Roland Scheidegger <[email protected]> Cc: 10.2 10.3 <[email protected]>
Diffstat (limited to 'src/gallium/drivers/llvmpipe')
-rw-r--r--src/gallium/drivers/llvmpipe/lp_rast.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c
index a3420a21fbf..6b54d4374f7 100644
--- a/src/gallium/drivers/llvmpipe/lp_rast.c
+++ b/src/gallium/drivers/llvmpipe/lp_rast.c
@@ -800,6 +800,8 @@ static PIPE_THREAD_ROUTINE( thread_function, init_data )
pipe_semaphore_signal(&task->work_done);
}
+ pipe_semaphore_signal(&task->work_done);
+
return 0;
}
@@ -885,9 +887,11 @@ void lp_rast_destroy( struct lp_rasterizer *rast )
pipe_semaphore_signal(&rast->tasks[i].work_ready);
}
- /* Wait for threads to terminate before cleaning up per-thread data */
+ /* Wait for threads to terminate before cleaning up per-thread data.
+ * We don't actually call pipe_thread_wait to avoid dead lock on Windows
+ * per https://bugs.freedesktop.org/show_bug.cgi?id=76252 */
for (i = 0; i < rast->num_threads; i++) {
- pipe_thread_wait(rast->threads[i]);
+ pipe_semaphore_wait(&rast->tasks[i].work_done);
}
/* Clean up per-thread data */