summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenri Verbeet <hverbeet@gmail.com>2011-01-29 15:00:48 -0800
committerBrian Paul <brianp@vmware.com>2011-01-31 09:29:54 -0700
commitbfc889517ad0d490cce1817eecac146d66bcd923 (patch)
tree584a723e55c950eedb8fa2d7f0195bd475ae7ffe
parentcbe9fc12a64c3ae89fd1b20e9e165aa4b76293a5 (diff)
glx: Fix leaks in DRI2 screen creation error paths.
Signed-off-by: Brian Paul <brianp@vmware.com>
-rw-r--r--src/glx/dri2_glx.c12
-rw-r--r--src/glx/glxclient.h2
-rw-r--r--src/glx/glxext.c28
3 files changed, 28 insertions, 14 deletions
diff --git a/src/glx/dri2_glx.c b/src/glx/dri2_glx.c
index 75b1a103f01..ab7915c02ee 100644
--- a/src/glx/dri2_glx.c
+++ b/src/glx/dri2_glx.c
@@ -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))
+ 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;
}
diff --git a/src/glx/glxclient.h b/src/glx/glxclient.h
index 36a0808c048..fdcef8075a8 100644
--- a/src/glx/glxclient.h
+++ b/src/glx/glxclient.h
@@ -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 *
diff --git a/src/glx/glxext.c b/src/glx/glxext.c
index c75c9bfd329..25d266e18e1 100644
--- a/src/glx/glxext.c
+++ b/src/glx/glxext.c
@@ -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.