From bfc889517ad0d490cce1817eecac146d66bcd923 Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Sat, 29 Jan 2011 15:00:48 -0800 Subject: [PATCH] glx: Fix leaks in DRI2 screen creation error paths. Signed-off-by: Brian Paul --- src/glx/dri2_glx.c | 14 ++++++++++---- src/glx/glxclient.h | 2 ++ src/glx/glxext.c | 28 +++++++++++++++++----------- 3 files changed, 29 insertions(+), 15 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)) - 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; } 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. -- 2.30.2