driDestroyDisplay: Remove Drivers list entry when dlclosing its handle.
authorMichel Dänzer <michel@tungstengraphics.com>
Thu, 1 Feb 2007 09:43:10 +0000 (10:43 +0100)
committerMichel Dänzer <michel@tungstengraphics.com>
Thu, 1 Feb 2007 09:43:10 +0000 (10:43 +0100)
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.

src/glx/x11/dri_glx.c

index 0875361d0b60256c662e6eda3e3bb4ca5ad5abb3..5ff1a94c7167114c6a5f4a96b7e25f1786782275 100644 (file)
@@ -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);