From 758b525463cd00478bf071d477ab58c92414b852 Mon Sep 17 00:00:00 2001 From: Kyle Brenneman Date: Tue, 25 Oct 2016 17:32:47 -0600 Subject: [PATCH 1/2] GLdispatch: Don't call into the vendor from __glDispatchForceUnpatch. In __glDispatchForceUnpatch, don't call the vendor's releasePatch callback, because the vendor library might have already been unloaded by that point. --- src/GLdispatch/GLdispatch.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/GLdispatch/GLdispatch.c b/src/GLdispatch/GLdispatch.c index 8c4c3a70..cf4254e6 100644 --- a/src/GLdispatch/GLdispatch.c +++ b/src/GLdispatch/GLdispatch.c @@ -570,8 +570,10 @@ static int PatchEntrypoints( if (stubCurrentPatchCb) { // Notify the previous vendor that it no longer owns these - // entrypoints. - if (stubCurrentPatchCb->releasePatch != NULL) { + // entrypoints. If this is being called from a library unload, + // though, then skip the callback, because the vendor may have + // already been unloaded. + if (stubCurrentPatchCb->releasePatch != NULL && !force) { stubCurrentPatchCb->releasePatch(); } From 8146a979d85e975587f3a20f0a6fdc2f04fa478f Mon Sep 17 00:00:00 2001 From: Kyle Brenneman Date: Tue, 25 Oct 2016 17:34:26 -0600 Subject: [PATCH 2/2] EGL: Don't call into the vendor library from __eglFini. In __eglFini, check for a fork, but don't call __glDispatchCheckMultithreaded. If a vendor has patched the OpenGL entrypoints, then __glDispatchCheckMultithreaded will try to call the vendor's thread attach callback, but the vendor library may have already been unloaded. Fixes https://github.com/NVIDIA/libglvnd/issues/103 --- src/EGL/libegl.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/EGL/libegl.c b/src/EGL/libegl.c index 65e66053..e0a54889 100644 --- a/src/EGL/libegl.c +++ b/src/EGL/libegl.c @@ -1088,7 +1088,7 @@ static void __eglResetOnFork(void); * Currently, this only detects whether a fork occurred since the last * entrypoint was called, and performs recovery as needed. */ -void __eglThreadInitialize(void) +void CheckFork(void) { volatile static int g_threadsInCheck = 0; volatile static int g_lastPid = -1; @@ -1120,7 +1120,11 @@ void __eglThreadInitialize(void) sched_yield(); } } +} +void __eglThreadInitialize(void) +{ + CheckFork(); __glDispatchCheckMultithreaded(); } @@ -1190,7 +1194,7 @@ void _fini(void) #endif { /* Check for a fork before going further. */ - __eglThreadInitialize(); + CheckFork(); /* * If libEGL owns the current API state, lose current