diff options
author | Michel Dänzer <michel@tungstengraphics.com> | 2007-02-01 10:43:10 +0100 |
---|---|---|
committer | Michel Dänzer <michel@tungstengraphics.com> | 2007-02-01 10:43:10 +0100 |
commit | bed026e7dda14ac1c555f1fb16d70eadcd1a01fc (patch) | |
tree | 5624ad4de8140ec03b121e126d3c22ceebba8f9b | |
parent | a2104dc6e18879ed3ba2108a09b6779e461eaa17 (diff) |
driDestroyDisplay: Remove Drivers list entry when dlclosing its handle.
This fixes a regression from commit f81b1dbe374fe446f6ef676e70a72952ffb47d4e:
Since then, driDestroyDisplay gets called from __glXFreeDisplayPrivate. It
dlcloses the handles associated with the display but fails to remove their
references from the Drivers list, so subsequent calls to OpenDriver return a
stale handle and an invalid createNewScreenFunc pointer. The attempt to call
the latter results in a segfault when running amoeba, e.g.
-rw-r--r-- | src/glx/x11/dri_glx.c | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/src/glx/x11/dri_glx.c b/src/glx/x11/dri_glx.c index 0875361d0b..5ff1a94c71 100644 --- a/src/glx/x11/dri_glx.c +++ b/src/glx/x11/dri_glx.c @@ -386,8 +386,24 @@ static void driDestroyDisplay(Display *dpy, void *private) const int numScreens = ScreenCount(dpy); int i; for (i = 0; i < numScreens; i++) { - if (pdpyp->libraryHandles[i]) - dlclose(pdpyp->libraryHandles[i]); + if (pdpyp->libraryHandles[i]) { + __DRIdriver *driver, *prev; + + /* Remove driver from Drivers list */ + for (prev = NULL, driver = Drivers; driver; + prev = driver, driver = driver->next) { + if (driver->handle == pdpyp->libraryHandles[i]) { + if (prev) + prev->next = driver->next; + else + Drivers = driver->next; + + Xfree(driver); + } + } + + dlclose(pdpyp->libraryHandles[i]); + } } Xfree(pdpyp->libraryHandles); Xfree(pdpyp); |