DRI2: handle drawable destruction properly at DRI2SwapComplete time
Simon reported an issue with kwin that turned out to be a general problem. If a drawable goes away before its swap completes, we'll try to free it up. However, we free it improperly, which causes a server crash in DRI2DestroyDrawable. Fix that up by splitting the free code out and calling it from DRI2SwapComplete. Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> Reviewed-by: Michel Dänzer <michel@daenzer.net> Signed-off-by: Keith Packard <keithp@keithp.com>
This commit is contained in:
		
							parent
							
								
									b68f0204a2
								
							
						
					
					
						commit
						711e26466a
					
				| 
						 | 
				
			
			@ -158,6 +158,31 @@ DRI2CreateDrawable(DrawablePtr pDraw)
 | 
			
		|||
    return Success;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
DRI2FreeDrawable(DrawablePtr pDraw)
 | 
			
		||||
{
 | 
			
		||||
    DRI2DrawablePtr pPriv;
 | 
			
		||||
    WindowPtr  	    pWin;
 | 
			
		||||
    PixmapPtr	    pPixmap;
 | 
			
		||||
 | 
			
		||||
    pPriv = DRI2GetDrawable(pDraw);
 | 
			
		||||
    if (pPriv == NULL)
 | 
			
		||||
	return;
 | 
			
		||||
 | 
			
		||||
    xfree(pPriv);
 | 
			
		||||
 | 
			
		||||
    if (pDraw->type == DRAWABLE_WINDOW)
 | 
			
		||||
    {
 | 
			
		||||
	pWin = (WindowPtr) pDraw;
 | 
			
		||||
	dixSetPrivate(&pWin->devPrivates, dri2WindowPrivateKey, NULL);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
	pPixmap = (PixmapPtr) pDraw;
 | 
			
		||||
	dixSetPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey, NULL);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
find_attachment(DRI2DrawablePtr pPriv, unsigned attachment)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -508,7 +533,7 @@ DRI2SwapComplete(ClientPtr client, DrawablePtr pDraw, int frame,
 | 
			
		|||
    if (pPriv->refCount == 0) {
 | 
			
		||||
        xf86DrvMsg(pScreen->myNum, X_ERROR,
 | 
			
		||||
		   "[DRI2] %s: bad drawable refcount\n", __func__);
 | 
			
		||||
	xfree(pPriv);
 | 
			
		||||
	DRI2FreeDrawable(pDraw);
 | 
			
		||||
	return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -729,8 +754,6 @@ DRI2DestroyDrawable(DrawablePtr pDraw)
 | 
			
		|||
{
 | 
			
		||||
    DRI2ScreenPtr   ds = DRI2GetScreen(pDraw->pScreen);
 | 
			
		||||
    DRI2DrawablePtr pPriv;
 | 
			
		||||
    WindowPtr  	    pWin;
 | 
			
		||||
    PixmapPtr	    pPixmap;
 | 
			
		||||
 | 
			
		||||
    pPriv = DRI2GetDrawable(pDraw);
 | 
			
		||||
    if (pPriv == NULL)
 | 
			
		||||
| 
						 | 
				
			
			@ -753,18 +776,7 @@ DRI2DestroyDrawable(DrawablePtr pDraw)
 | 
			
		|||
     * actually free the priv yet.  We'll need it in the DRI2SwapComplete()
 | 
			
		||||
     * callback and we'll free it there once we're done. */
 | 
			
		||||
    if (!pPriv->swapsPending)
 | 
			
		||||
	xfree(pPriv);
 | 
			
		||||
 | 
			
		||||
    if (pDraw->type == DRAWABLE_WINDOW)
 | 
			
		||||
    {
 | 
			
		||||
	pWin = (WindowPtr) pDraw;
 | 
			
		||||
	dixSetPrivate(&pWin->devPrivates, dri2WindowPrivateKey, NULL);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
	pPixmap = (PixmapPtr) pDraw;
 | 
			
		||||
	dixSetPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey, NULL);
 | 
			
		||||
    }
 | 
			
		||||
	DRI2FreeDrawable(pDraw);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Bool
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue