glx: Fix leaks in DRI2 screen creation error paths.
authorHenri Verbeet <hverbeet@gmail.com>
Sat, 29 Jan 2011 23:00:48 +0000 (15:00 -0800)
committerBrian Paul <brianp@vmware.com>
Mon, 31 Jan 2011 16:29:54 +0000 (09:29 -0700)
Signed-off-by: Brian Paul <brianp@vmware.com>
src/glx/dri2_glx.c
src/glx/glxclient.h
src/glx/glxext.c

index 75b1a103f0145b9c1af51ea842e1e9774a0cec83..ab7915c02ee502c8869a1f37fb1b03a5c820c0f6 100644 (file)
@@ -804,11 +804,14 @@ dri2CreateScreen(int screen, struct glx_display * priv)
       return NULL;
 
    memset(psc, 0, sizeof *psc);
-   if (!glx_screen_init(&psc->base, screen, priv))
-       return NULL;
+   if (!glx_screen_init(&psc->base, screen, priv)) {
+      Xfree(psc);
+      return NULL;
+   }
 
    if (!DRI2Connect(priv->dpy, RootWindow(priv->dpy, screen),
                    &driverName, &deviceName)) {
+      glx_screen_cleanup(&psc->base);
       XFree(psc);
       return NULL;
    }
@@ -918,12 +921,15 @@ dri2CreateScreen(int screen, struct glx_display * priv)
    return &psc->base;
 
 handle_error:
+   if (psc->fd)
+      close(psc->fd);
+   if (psc->driver)
+      dlclose(psc->driver);
    Xfree(driverName);
    Xfree(deviceName);
+   glx_screen_cleanup(&psc->base);
    XFree(psc);
 
-   /* FIXME: clean up here */
-
    return NULL;
 }
 
index 36a0808c048a05c2ae07435cd359bd0881460709..fdcef8075a89a92ebc355fd3b584e16e0f1da3a1 100644 (file)
@@ -585,6 +585,8 @@ struct glx_display
 extern int
 glx_screen_init(struct glx_screen *psc,
                int screen, struct glx_display * priv);
+extern void
+glx_screen_cleanup(struct glx_screen *psc);
 
 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
 extern __GLXDRIdrawable *
index c75c9bfd32918f010c535651e1eb3b54d53ff8cf..25d266e18e137bcf6bd4150296dd10a6c62d92fb 100644 (file)
@@ -194,17 +194,7 @@ FreeScreenConfigs(struct glx_display * priv)
    screens = ScreenCount(priv->dpy);
    for (i = 0; i < screens; i++) {
       psc = priv->screens[i];
-      if (psc->configs) {
-        glx_config_destroy_list(psc->configs);
-         if (psc->effectiveGLXexts)
-            Xfree(psc->effectiveGLXexts);
-         psc->configs = NULL;   /* NOTE: just for paranoia */
-      }
-      if (psc->visuals) {
-        glx_config_destroy_list(psc->visuals);
-        psc->visuals = NULL;   /* NOTE: just for paranoia */
-      }
-      Xfree((char *) psc->serverGLXexts);
+      glx_screen_cleanup(psc);
 
 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
       if (psc->driScreen) {
@@ -728,6 +718,22 @@ glx_screen_init(struct glx_screen *psc,
    return GL_TRUE;
 }
 
+_X_HIDDEN void
+glx_screen_cleanup(struct glx_screen *psc)
+{
+   if (psc->configs) {
+      glx_config_destroy_list(psc->configs);
+      if (psc->effectiveGLXexts)
+          Xfree(psc->effectiveGLXexts);
+      psc->configs = NULL;   /* NOTE: just for paranoia */
+   }
+   if (psc->visuals) {
+      glx_config_destroy_list(psc->visuals);
+      psc->visuals = NULL;   /* NOTE: just for paranoia */
+   }
+   Xfree((char *) psc->serverGLXexts);
+}
+
 /*
 ** Allocate the memory for the per screen configs for each screen.
 ** If that works then fetch the per screen configs data.