summaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/dri/common
diff options
context:
space:
mode:
authorDave Airlie <[email protected]>2009-04-16 13:06:24 +1000
committerDave Airlie <[email protected]>2009-04-16 13:06:24 +1000
commit3264352c577ce1d6681e70abd76624ede906df71 (patch)
tree289c835a18c6beecbd83a956d20ad0c01dd36003 /src/mesa/drivers/dri/common
parent143b416af6662995059cd5209a750dbace78081c (diff)
dri: attempt to actually refcount the __DRIDrawable
valgrind was showing a race between the drawable getting destroyed by the X resource freeing code, and the context getting destroyed later and freeing the drawable. However I've no idea if some other combination of things could cause this code to leak.
Diffstat (limited to 'src/mesa/drivers/dri/common')
-rw-r--r--src/mesa/drivers/dri/common/dri_util.c32
1 files changed, 24 insertions, 8 deletions
diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c
index 38c2e7b00d1..0ec4adc2325 100644
--- a/src/mesa/drivers/dri/common/dri_util.c
+++ b/src/mesa/drivers/dri/common/dri_util.c
@@ -37,6 +37,9 @@
typedef GLboolean ( * PFNGLXGETMSCRATEOMLPROC) (__DRIdrawable *drawable, int32_t *numerator, int32_t *denominator);
#endif
+static void dri_get_drawable(__DRIdrawable *pdp);
+static void dri_put_drawable(__DRIdrawable *pdp);
+
/**
* This is just a token extension used to signal that the driver
* supports setting a read drawable.
@@ -127,7 +130,7 @@ static int driUnbindContext(__DRIcontext *pcp)
return GL_FALSE;
}
- pdp->refcount--;
+ dri_put_drawable(pdp);
if (prp != pdp) {
if (prp->refcount == 0) {
@@ -135,7 +138,7 @@ static int driUnbindContext(__DRIcontext *pcp)
return GL_FALSE;
}
- prp->refcount--;
+ dri_put_drawable(prp);
}
@@ -170,10 +173,10 @@ static int driBindContext(__DRIcontext *pcp,
pcp->driReadablePriv = prp;
if (pdp) {
pdp->driContextPriv = pcp;
- pdp->refcount++;
+ dri_get_drawable(pdp);
}
if ( prp && pdp != prp ) {
- prp->refcount++;
+ dri_get_drawable(prp);
}
}
@@ -430,7 +433,7 @@ driCreateNewDrawable(__DRIscreen *psp, const __DRIconfig *config,
pdp->loaderPrivate = data;
pdp->hHWDrawable = hwDrawable;
- pdp->refcount = 0;
+ pdp->refcount = 1;
pdp->pStamp = NULL;
pdp->lastStamp = 0;
pdp->index = 0;
@@ -483,12 +486,19 @@ dri2CreateNewDrawable(__DRIscreen *screen,
return pdraw;
}
-
-static void
-driDestroyDrawable(__DRIdrawable *pdp)
+static void dri_get_drawable(__DRIdrawable *pdp)
+{
+ pdp->refcount++;
+}
+
+static void dri_put_drawable(__DRIdrawable *pdp)
{
__DRIscreenPrivate *psp;
+ pdp->refcount--;
+ if (pdp->refcount)
+ return;
+
if (pdp) {
psp = pdp->driScreenPriv;
(*psp->DriverAPI.DestroyBuffer)(pdp);
@@ -504,6 +514,12 @@ driDestroyDrawable(__DRIdrawable *pdp)
}
}
+static void
+driDestroyDrawable(__DRIdrawable *pdp)
+{
+ dri_put_drawable(pdp);
+}
+
/*@}*/