Module Name:    xsrc
Committed By:   jmmv
Date:           Fri Mar 18 09:51:00 UTC 2011

Modified Files:
        xsrc/external/mit/xorg-server/dist/glx: glxcmds.c glxdrawable.h
            glxext.c

Log Message:
Pull up fix from https://bugs.freedesktop.org/show_bug.cgi?id=28181 to
prevent random segfaults of the X server when using composite with the
ati driver.

This makes my X session rock solid when running KDE 4.5 on a MacBookPro
2,2 with an ATI Radeon Mobility X1600.  The X server was crashing very
frequently before.

OKed by mrg@ and macallan@.  Addresses PR xsrc/44730.


To generate a diff of this commit:
cvs rdiff -u -r1.1.1.3 -r1.2 xsrc/external/mit/xorg-server/dist/glx/glxcmds.c \
    xsrc/external/mit/xorg-server/dist/glx/glxdrawable.h \
    xsrc/external/mit/xorg-server/dist/glx/glxext.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: xsrc/external/mit/xorg-server/dist/glx/glxcmds.c
diff -u xsrc/external/mit/xorg-server/dist/glx/glxcmds.c:1.1.1.3 xsrc/external/mit/xorg-server/dist/glx/glxcmds.c:1.2
--- xsrc/external/mit/xorg-server/dist/glx/glxcmds.c:1.1.1.3	Tue Nov 23 05:21:07 2010
+++ xsrc/external/mit/xorg-server/dist/glx/glxcmds.c	Fri Mar 18 09:51:00 2011
@@ -530,6 +530,7 @@
 	*error = BadAlloc;
 	return NULL;
     }
+    pGlxDraw->refcnt++;
 
     return pGlxDraw;
 }
@@ -1100,8 +1101,10 @@
     drawable->pDraw = pDraw;
     drawable->type = type;
     drawable->drawId = drawId;
+    drawable->otherId = 0;
     drawable->config = config;
     drawable->eventMask = 0;
+    drawable->refcnt = 0;
 
     return GL_TRUE;
 }
@@ -1131,14 +1134,18 @@
 	pGlxDraw->destroy (pGlxDraw);
 	return BadAlloc;
     }
+    pGlxDraw->refcnt++;
 
-    /* Add the glx drawable under the XID of the underlying X drawable
-     * too.  That way we'll get a callback in DrawableGone and can
-     * clean up properly when the drawable is destroyed. */
-    if (drawableId != glxDrawableId &&
-	!AddResource(pDraw->id, __glXDrawableRes, pGlxDraw)) {
-	pGlxDraw->destroy (pGlxDraw);
-	return BadAlloc;
+    if (drawableId != glxDrawableId) {
+	/* Add the glx drawable under the XID of the underlying X drawable
+	 * too.  That way we'll get a callback in DrawableGone and can
+	 * clean up properly when the drawable is destroyed. */
+	if (!AddResource(drawableId, __glXDrawableRes, pGlxDraw)) {
+	    pGlxDraw->destroy (pGlxDraw);
+	    return BadAlloc;
+	}
+	pGlxDraw->refcnt++;
+	pGlxDraw->otherId = drawableId;
     }
 
     return Success;
Index: xsrc/external/mit/xorg-server/dist/glx/glxdrawable.h
diff -u xsrc/external/mit/xorg-server/dist/glx/glxdrawable.h:1.1.1.3 xsrc/external/mit/xorg-server/dist/glx/glxdrawable.h:1.2
--- xsrc/external/mit/xorg-server/dist/glx/glxdrawable.h:1.1.1.3	Tue Nov 23 05:21:08 2010
+++ xsrc/external/mit/xorg-server/dist/glx/glxdrawable.h	Fri Mar 18 09:51:00 2011
@@ -51,8 +51,11 @@
     void      (*waitX)(__GLXdrawable *);
     void      (*waitGL)(__GLXdrawable *);
 
+    int refcnt; /* number of resources handles referencing this */
+
     DrawablePtr pDraw;
     XID drawId;
+    XID otherId; /* for glx1.3 we need to track the original Drawable as well */
 
     /*
     ** Either GLX_DRAWABLE_PIXMAP, GLX_DRAWABLE_WINDOW or
Index: xsrc/external/mit/xorg-server/dist/glx/glxext.c
diff -u xsrc/external/mit/xorg-server/dist/glx/glxext.c:1.1.1.3 xsrc/external/mit/xorg-server/dist/glx/glxext.c:1.2
--- xsrc/external/mit/xorg-server/dist/glx/glxext.c:1.1.1.3	Tue Nov 23 05:21:08 2010
+++ xsrc/external/mit/xorg-server/dist/glx/glxext.c	Fri Mar 18 09:51:00 2011
@@ -130,13 +130,18 @@
      * constructors, we added it as a glx drawable resource under both
      * its glx drawable ID and it X drawable ID.  Remove the other
      * resource now so we don't a callback for freed memory. */
-    if (glxPriv->drawId != glxPriv->pDraw->id) {
-	if (xid == glxPriv->drawId)
-	    FreeResourceByType(glxPriv->pDraw->id, __glXDrawableRes, TRUE);
-	else
-	    FreeResourceByType(glxPriv->drawId, __glXDrawableRes, TRUE);
+    if (glxPriv->otherId) {
+	    XID other = glxPriv->otherId;
+	    glxPriv->otherId = 0;
+	    if (xid == other)
+		    FreeResourceByType(glxPriv->drawId, __glXDrawableRes, TRUE);
+	    else
+		    FreeResourceByType(other, __glXDrawableRes, TRUE);
     }
 
+    if (--glxPriv->refcnt)
+	    return True;
+
     for (c = glxAllContexts; c; c = next) {
 	next = c->next;
 	if (c->isCurrent && (c->drawPriv == glxPriv || c->readPriv == glxPriv)) {

Reply via email to