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;
 | 
					    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
 | 
					static int
 | 
				
			||||||
find_attachment(DRI2DrawablePtr pPriv, unsigned attachment)
 | 
					find_attachment(DRI2DrawablePtr pPriv, unsigned attachment)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -508,7 +533,7 @@ DRI2SwapComplete(ClientPtr client, DrawablePtr pDraw, int frame,
 | 
				
			||||||
    if (pPriv->refCount == 0) {
 | 
					    if (pPriv->refCount == 0) {
 | 
				
			||||||
        xf86DrvMsg(pScreen->myNum, X_ERROR,
 | 
					        xf86DrvMsg(pScreen->myNum, X_ERROR,
 | 
				
			||||||
		   "[DRI2] %s: bad drawable refcount\n", __func__);
 | 
							   "[DRI2] %s: bad drawable refcount\n", __func__);
 | 
				
			||||||
	xfree(pPriv);
 | 
						DRI2FreeDrawable(pDraw);
 | 
				
			||||||
	return;
 | 
						return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -729,8 +754,6 @@ DRI2DestroyDrawable(DrawablePtr pDraw)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    DRI2ScreenPtr   ds = DRI2GetScreen(pDraw->pScreen);
 | 
					    DRI2ScreenPtr   ds = DRI2GetScreen(pDraw->pScreen);
 | 
				
			||||||
    DRI2DrawablePtr pPriv;
 | 
					    DRI2DrawablePtr pPriv;
 | 
				
			||||||
    WindowPtr  	    pWin;
 | 
					 | 
				
			||||||
    PixmapPtr	    pPixmap;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pPriv = DRI2GetDrawable(pDraw);
 | 
					    pPriv = DRI2GetDrawable(pDraw);
 | 
				
			||||||
    if (pPriv == NULL)
 | 
					    if (pPriv == NULL)
 | 
				
			||||||
| 
						 | 
					@ -753,18 +776,7 @@ DRI2DestroyDrawable(DrawablePtr pDraw)
 | 
				
			||||||
     * actually free the priv yet.  We'll need it in the DRI2SwapComplete()
 | 
					     * actually free the priv yet.  We'll need it in the DRI2SwapComplete()
 | 
				
			||||||
     * callback and we'll free it there once we're done. */
 | 
					     * callback and we'll free it there once we're done. */
 | 
				
			||||||
    if (!pPriv->swapsPending)
 | 
					    if (!pPriv->swapsPending)
 | 
				
			||||||
	xfree(pPriv);
 | 
						DRI2FreeDrawable(pDraw);
 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (pDraw->type == DRAWABLE_WINDOW)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
	pWin = (WindowPtr) pDraw;
 | 
					 | 
				
			||||||
	dixSetPrivate(&pWin->devPrivates, dri2WindowPrivateKey, NULL);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
	pPixmap = (PixmapPtr) pDraw;
 | 
					 | 
				
			||||||
	dixSetPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey, NULL);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Bool
 | 
					Bool
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue