summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@redhat.com>2009-04-09 13:16:37 -0400
committerKristian Høgsberg <krh@redhat.com>2009-04-13 13:17:53 -0400
commit7b6400a1b8d2f228fcbedf17c30a7e3924e4dd2a (patch)
tree81755c27fb2cc6997c9ba3997ca1e42d3cd133e4
parent140463a197fb93d0a4bfad924efc35b860e8cc54 (diff)
glx: Fix drawable private leak on destroy
When a drawable goes away, we don't destroy the GLX drawable in full, since it may be current for a context. This means that when the drawable is destroyed in full later, the backend doesn't get a chance to destroy resources associated with the drawable (the DRI2Drawable). With this patch, we destroy the GLX drawable in full when it goes away and then track down all contexts that reference it and NULL their pointers.
-rw-r--r--glx/Makefile.am1
-rw-r--r--glx/glxcmds.c44
-rw-r--r--glx/glxdrawable.h5
-rw-r--r--glx/glxdri.c2
-rw-r--r--glx/glxdri2.c2
-rw-r--r--glx/glxdriswrast.c2
-rw-r--r--glx/glxext.c42
-rw-r--r--glx/glxext.h1
-rw-r--r--glx/glxutil.c74
-rw-r--r--glx/glxutil.h9
10 files changed, 67 insertions, 115 deletions
diff --git a/glx/Makefile.am b/glx/Makefile.am
index 2537db865..a23ae0a47 100644
--- a/glx/Makefile.am
+++ b/glx/Makefile.am
@@ -80,7 +80,6 @@ libglx_la_SOURCES = \
80 glxscreens.c \ 80 glxscreens.c \
81 glxscreens.h \ 81 glxscreens.h \
82 glxserver.h \ 82 glxserver.h \
83 glxutil.c \
84 glxutil.h \ 83 glxutil.h \
85 render2.c \ 84 render2.c \
86 render2swap.c \ 85 render2swap.c \
diff --git a/glx/glxcmds.c b/glx/glxcmds.c
index e21f0f098..86e8dd8a5 100644
--- a/glx/glxcmds.c
+++ b/glx/glxcmds.c
@@ -193,18 +193,9 @@ validGlxDrawable(ClientPtr client, XID id, int type, int access_mode,
193void 193void
194__glXContextDestroy(__GLXcontext *context) 194__glXContextDestroy(__GLXcontext *context)
195{ 195{
196 if (!context->isDirect) {
197 if (context->drawPriv)
198 __glXUnrefDrawable(context->drawPriv);
199 if (context->readPriv)
200 __glXUnrefDrawable(context->readPriv);
201 context->drawPriv = NULL;
202 context->readPriv = NULL;
203 }
204 __glXFlushContextCache(); 196 __glXFlushContextCache();
205} 197}
206 198
207
208static void __glXdirectContextDestroy(__GLXcontext *context) 199static void __glXdirectContextDestroy(__GLXcontext *context)
209{ 200{
210 __glXContextDestroy(context); 201 __glXContextDestroy(context);
@@ -320,6 +311,8 @@ DoCreateContext(__GLXclientState *cl, GLXContextID gcId,
320 glxc->isDirect = isDirect; 311 glxc->isDirect = isDirect;
321 glxc->renderMode = GL_RENDER; 312 glxc->renderMode = GL_RENDER;
322 313
314 __glXAddToContextList(glxc);
315
323 return Success; 316 return Success;
324} 317}
325 318
@@ -639,10 +632,6 @@ DoMakeCurrent(__GLXclientState *cl,
639 } 632 }
640 __glXFlushContextCache(); 633 __glXFlushContextCache();
641 if (!prevglxc->isDirect) { 634 if (!prevglxc->isDirect) {
642 if (prevglxc->drawPriv)
643 __glXUnrefDrawable(prevglxc->drawPriv);
644 if (prevglxc->readPriv)
645 __glXUnrefDrawable(prevglxc->readPriv);
646 prevglxc->drawPriv = NULL; 635 prevglxc->drawPriv = NULL;
647 prevglxc->readPriv = NULL; 636 prevglxc->readPriv = NULL;
648 } 637 }
@@ -662,8 +651,6 @@ DoMakeCurrent(__GLXclientState *cl,
662 } 651 }
663 652
664 glxc->isCurrent = GL_TRUE; 653 glxc->isCurrent = GL_TRUE;
665 __glXRefDrawable(glxc->drawPriv);
666 __glXRefDrawable(glxc->readPriv);
667 } 654 }
668 655
669 if (prevglxc) { 656 if (prevglxc) {
@@ -1090,6 +1077,33 @@ int __glXDisp_GetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc)
1090 return DoGetFBConfigs(cl, req->screen); 1077 return DoGetFBConfigs(cl, req->screen);
1091} 1078}
1092 1079
1080GLboolean
1081__glXDrawableInit(__GLXdrawable *drawable,
1082 __GLXscreen *screen, DrawablePtr pDraw, int type,
1083 XID drawId, __GLXconfig *config)
1084{
1085 drawable->pDraw = pDraw;
1086 drawable->type = type;
1087 drawable->drawId = drawId;
1088 drawable->config = config;
1089 drawable->eventMask = 0;
1090
1091 return GL_TRUE;
1092}
1093
1094void
1095__glXDrawableRelease(__GLXdrawable *drawable)
1096{
1097 ScreenPtr pScreen = drawable->pDraw->pScreen;
1098
1099 switch (drawable->type) {
1100 case GLX_DRAWABLE_PIXMAP:
1101 case GLX_DRAWABLE_PBUFFER:
1102 (*pScreen->DestroyPixmap)((PixmapPtr) drawable->pDraw);
1103 break;
1104 }
1105}
1106
1093static int 1107static int
1094DoCreateGLXDrawable(ClientPtr client, __GLXscreen *pGlxScreen, __GLXconfig *config, 1108DoCreateGLXDrawable(ClientPtr client, __GLXscreen *pGlxScreen, __GLXconfig *config,
1095 DrawablePtr pDraw, XID glxDrawableId, int type) 1109 DrawablePtr pDraw, XID glxDrawableId, int type)
diff --git a/glx/glxdrawable.h b/glx/glxdrawable.h
index b64ff35c9..0215b3b20 100644
--- a/glx/glxdrawable.h
+++ b/glx/glxdrawable.h
@@ -67,11 +67,6 @@ struct __GLXdrawable {
67 */ 67 */
68 __GLXconfig *config; 68 __GLXconfig *config;
69 69
70 /*
71 ** reference count
72 */
73 int refCount;
74
75 GLenum target; 70 GLenum target;
76 GLenum format; 71 GLenum format;
77 72
diff --git a/glx/glxdri.c b/glx/glxdri.c
index cc6d93976..eeac7fcb2 100644
--- a/glx/glxdri.c
+++ b/glx/glxdri.c
@@ -238,6 +238,8 @@ __glXDRIdrawableDestroy(__GLXdrawable *drawable)
238 __glXleaveServer(GL_FALSE); 238 __glXleaveServer(GL_FALSE);
239 } 239 }
240 240
241 __glXDrawableRelease(drawable);
242
241 xfree(private); 243 xfree(private);
242} 244}
243 245
diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index ea5b5ef72..9dac8a6a3 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -109,6 +109,8 @@ __glXDRIdrawableDestroy(__GLXdrawable *drawable)
109 if (drawable->pDraw != NULL) 109 if (drawable->pDraw != NULL)
110 DRI2DestroyDrawable(drawable->pDraw); 110 DRI2DestroyDrawable(drawable->pDraw);
111 111
112 __glXDrawableRelease(drawable);
113
112 xfree(private); 114 xfree(private);
113} 115}
114 116
diff --git a/glx/glxdriswrast.c b/glx/glxdriswrast.c
index de89d381e..328aa7e56 100644
--- a/glx/glxdriswrast.c
+++ b/glx/glxdriswrast.c
@@ -102,6 +102,8 @@ __glXDRIdrawableDestroy(__GLXdrawable *drawable)
102 FreeScratchGC(private->gc); 102 FreeScratchGC(private->gc);
103 FreeScratchGC(private->swapgc); 103 FreeScratchGC(private->swapgc);
104 104
105 __glXDrawableRelease(drawable);
106
105 xfree(private); 107 xfree(private);
106} 108}
107 109
diff --git a/glx/glxext.c b/glx/glxext.c
index 025e6198f..93391e9fd 100644
--- a/glx/glxext.c
+++ b/glx/glxext.c
@@ -50,6 +50,7 @@
50** from the server's perspective. 50** from the server's perspective.
51*/ 51*/
52__GLXcontext *__glXLastContext; 52__GLXcontext *__glXLastContext;
53__GLXcontext *__glXContextList;
53 54
54/* 55/*
55** X resources. 56** X resources.
@@ -111,31 +112,46 @@ static int ContextGone(__GLXcontext* cx, XID id)
111 return True; 112 return True;
112} 113}
113 114
115static __GLXcontext *glxPendingDestroyContexts;
116static __GLXcontext *glxAllContexts;
117static int glxServerLeaveCount;
118static int glxBlockClients;
119
114/* 120/*
115** Destroy routine that gets called when a drawable is freed. A drawable 121** Destroy routine that gets called when a drawable is freed. A drawable
116** contains the ancillary buffers needed for rendering. 122** contains the ancillary buffers needed for rendering.
117*/ 123*/
118static Bool DrawableGone(__GLXdrawable *glxPriv, XID xid) 124static Bool DrawableGone(__GLXdrawable *glxPriv, XID xid)
119{ 125{
120 ScreenPtr pScreen = glxPriv->pDraw->pScreen; 126 __GLXcontext *c;
121 127
122 switch (glxPriv->type) { 128 for (c = glxAllContexts; c; c = c->next) {
123 case GLX_DRAWABLE_PIXMAP: 129 if (c->drawPriv == glxPriv)
124 case GLX_DRAWABLE_PBUFFER: 130 c->drawPriv = NULL;
125 (*pScreen->DestroyPixmap)((PixmapPtr) glxPriv->pDraw); 131 if (c->readPriv == glxPriv)
126 break; 132 c->readPriv = NULL;
127 } 133 }
128 134
129 glxPriv->pDraw = NULL; 135 glxPriv->destroy(glxPriv);
130 glxPriv->drawId = 0;
131 __glXUnrefDrawable(glxPriv);
132 136
133 return True; 137 return True;
134} 138}
135 139
136static __GLXcontext *glxPendingDestroyContexts; 140void __glXAddToContextList(__GLXcontext *cx)
137static int glxServerLeaveCount; 141{
138static int glxBlockClients; 142 cx->next = glxAllContexts;
143 glxAllContexts = cx;
144}
145
146void __glXRemoveFromContextList(__GLXcontext *cx)
147{
148 __GLXcontext *c, **prev;
149
150 prev = &glxAllContexts;
151 for (c = glxAllContexts; c; c = c->next)
152 if (c == cx)
153 *prev = c->next;
154}
139 155
140/* 156/*
141** Free a context. 157** Free a context.
@@ -150,6 +166,8 @@ GLboolean __glXFreeContext(__GLXcontext *cx)
150 __glXFlushContextCache(); 166 __glXFlushContextCache();
151 } 167 }
152 168
169 __glXRemoveFromContextList(cx);
170
153 /* We can get here through both regular dispatching from 171 /* We can get here through both regular dispatching from
154 * __glXDispatch() or as a callback from the resource manager. In 172 * __glXDispatch() or as a callback from the resource manager. In
155 * the latter case we need to lift the DRI lock manually. */ 173 * the latter case we need to lift the DRI lock manually. */
diff --git a/glx/glxext.h b/glx/glxext.h
index 72092f34a..7008c4763 100644
--- a/glx/glxext.h
+++ b/glx/glxext.h
@@ -38,6 +38,7 @@
38extern GLboolean __glXFreeContext(__GLXcontext *glxc); 38extern GLboolean __glXFreeContext(__GLXcontext *glxc);
39extern void __glXFlushContextCache(void); 39extern void __glXFlushContextCache(void);
40 40
41extern void __glXAddToContextList(__GLXcontext *cx);
41extern void __glXErrorCallBack(GLenum code); 42extern void __glXErrorCallBack(GLenum code);
42extern void __glXClearErrorOccured(void); 43extern void __glXClearErrorOccured(void);
43extern GLboolean __glXErrorOccured(void); 44extern GLboolean __glXErrorOccured(void);
diff --git a/glx/glxutil.c b/glx/glxutil.c
deleted file mode 100644
index 52a10e4e5..000000000
--- a/glx/glxutil.c
+++ /dev/null
@@ -1,74 +0,0 @@
1/*
2 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
3 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice including the dates of first publication and
13 * either this permission notice or a reference to
14 * http://oss.sgi.com/projects/FreeB/
15 * shall be included in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
22 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 *
25 * Except as contained in this notice, the name of Silicon Graphics, Inc.
26 * shall not be used in advertising or otherwise to promote the sale, use or
27 * other dealings in this Software without prior written authorization from
28 * Silicon Graphics, Inc.
29 */
30
31#define FONT_PCF
32#ifdef HAVE_DIX_CONFIG_H
33#include <dix-config.h>
34#endif
35
36#include <string.h>
37
38#include "glxserver.h"
39#include "glxutil.h"
40
41/*****************************************************************************/
42/* Drawable private stuff */
43
44void
45__glXRefDrawable(__GLXdrawable *glxPriv)
46{
47 glxPriv->refCount++;
48}
49
50void
51__glXUnrefDrawable(__GLXdrawable *glxPriv)
52{
53 glxPriv->refCount--;
54 if (glxPriv->refCount == 0) {
55 /* remove the drawable from the drawable list */
56 FreeResourceByType(glxPriv->drawId, __glXDrawableRes, FALSE);
57 glxPriv->destroy(glxPriv);
58 }
59}
60
61GLboolean
62__glXDrawableInit(__GLXdrawable *drawable,
63 __GLXscreen *screen, DrawablePtr pDraw, int type,
64 XID drawId, __GLXconfig *config)
65{
66 drawable->pDraw = pDraw;
67 drawable->type = type;
68 drawable->drawId = drawId;
69 drawable->refCount = 1;
70 drawable->config = config;
71 drawable->eventMask = 0;
72
73 return GL_TRUE;
74}
diff --git a/glx/glxutil.h b/glx/glxutil.h
index baa490500..d1a715b4b 100644
--- a/glx/glxutil.h
+++ b/glx/glxutil.h
@@ -35,18 +35,11 @@
35 * Silicon Graphics, Inc. 35 * Silicon Graphics, Inc.
36 */ 36 */
37 37
38/* relate contexts with drawables */
39extern void __glXAssociateContext(__GLXcontext *glxc);
40extern void __glXDeassociateContext(__GLXcontext *glxc);
41
42/* drawable management */
43extern void __glXRefDrawable(__GLXdrawable *glxPriv);
44extern void __glXUnrefDrawable(__GLXdrawable *glxPriv);
45
46extern GLboolean __glXDrawableInit(__GLXdrawable *drawable, 38extern GLboolean __glXDrawableInit(__GLXdrawable *drawable,
47 __GLXscreen *screen, 39 __GLXscreen *screen,
48 DrawablePtr pDraw, int type, XID drawID, 40 DrawablePtr pDraw, int type, XID drawID,
49 __GLXconfig *config); 41 __GLXconfig *config);
42extern void __glXDrawableRelease(__GLXdrawable *drawable);
50 43
51/* context helper routines */ 44/* context helper routines */
52extern __GLXcontext *__glXLookupContextByTag(__GLXclientState*, GLXContextTag); 45extern __GLXcontext *__glXLookupContextByTag(__GLXclientState*, GLXContextTag);