egl: free display ext data in xdri_eglTerminate().
authorBrian Paul <brian.paul@tungstengraphics.com>
Wed, 27 Aug 2008 22:03:03 +0000 (16:03 -0600)
committerBrian Paul <brian.paul@tungstengraphics.com>
Wed, 27 Aug 2008 22:20:19 +0000 (16:20 -0600)
src/egl/drivers/xdri/egl_xdri.c

index 3681d9879a230820f9d551ce768e33b5e98ead2a..6a271ff577defb558fd70c7c091b8967b699560f 100644 (file)
@@ -651,6 +651,35 @@ xdri_eglInitialize(_EGLDriver *drv, EGLDisplay dpy,
 }
 
 
+/*
+ * Do some clean-up that normally occurs in XCloseDisplay().
+ * We do this here because we're about to unload a dynamic library
+ * that has added some per-display extension data and callbacks.
+ * If we don't do this here we'll crash in XCloseDisplay() because it'll
+ * try to call functions that went away when the driver library was unloaded.
+ */
+static void
+FreeDisplayExt(Display *dpy)
+{
+   _XExtension *ext, *next;
+
+   for (ext = dpy->ext_procs; ext; ext = next) {
+      next = ext->next;
+      if (ext->close_display) {
+         ext->close_display(dpy, &ext->codes);
+         ext->close_display = NULL;
+      }
+      if (ext->name)
+         Xfree(ext->name);
+      Xfree(ext);
+   }
+   dpy->ext_procs = NULL;
+
+   _XFreeExtData (dpy->ext_data);
+   dpy->ext_data = NULL;
+}
+
+
 /**
  * Called via eglTerminate(), drv->API.Terminate().
  */
@@ -658,11 +687,16 @@ static EGLBoolean
 xdri_eglTerminate(_EGLDriver *drv, EGLDisplay dpy)
 {
    struct xdri_egl_driver *xdri_drv = xdri_egl_driver(drv);
+   _EGLDisplay *disp = _eglLookupDisplay(dpy);
 
    _eglLog(_EGL_DEBUG, "XDRI: eglTerminate");
 
    _eglLog(_EGL_DEBUG, "XDRI: Closing %s", xdri_drv->dri_driver_name);
+
+   FreeDisplayExt(disp->Xdpy);
+
 #if 0
+   /* this causes a segfault for some reason */
    dlclose(xdri_drv->dri_driver_handle);
 #endif
    xdri_drv->dri_driver_handle = NULL;