On Mon, 2010-01-25 at 09:21 -0800, Jesse Barnes wrote: 
> 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.
> 
> Tested-by: Simon Thum <[email protected]>
> Signed-off-by: Jesse Barnes <[email protected]>

Reviewed-by: Michel Dänzer <[email protected]>

> diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
> index 3db826e..97c79d6 100644
> --- a/hw/xfree86/dri2/dri2.c
> +++ b/hw/xfree86/dri2/dri2.c
> @@ -157,6 +157,31 @@ DRI2CreateDrawable(DrawablePtr pDraw)
>      return Success;
>  }
>  
> +static void
> +DRI2FreeDrawable(DrawablePtr pDraw)
> +{
> +    DRI2DrawablePtr pPriv;
> +    WindowPtr            pWin;
> +    PixmapPtr            pPixmap;

Wonky whitespace.

> +    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)
>  {
> @@ -507,7 +532,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;
>      }
>  
> @@ -728,8 +753,6 @@ DRI2DestroyDrawable(DrawablePtr pDraw)
>  {
>      DRI2ScreenPtr   ds = DRI2GetScreen(pDraw->pScreen);
>      DRI2DrawablePtr pPriv;
> -    WindowPtr            pWin;
> -    PixmapPtr            pPixmap;
>  
>      pPriv = DRI2GetDrawable(pDraw);
>      if (pPriv == NULL)
> @@ -752,18 +775,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


-- 
Earthling Michel Dänzer           |                http://www.vmware.com
Libre software enthusiast         |          Debian, X and DRI developer
_______________________________________________
xorg-devel mailing list
[email protected]
http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to