[PATCH] DRI2: handle drawable destruction properly at DRI2SwapComplete time
Simon Thum
simon.thum at gmx.de
Mon Jan 25 11:21:12 PST 2010
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 <simon.thum at gmx.de>
Note I didn't test it, maybe you're missing out someone? But feel free
to add my
Reviewed-by: Simon Thum <simon.thum at gmx.de>
if there's no concurrency problem with
xfree(pPriv);
being executed before
dixSetPrivate(&pWin->devPrivates, dri2WindowPrivateKey, NULL);
(In case the swap stuff is parallelized somehow)
> Signed-off-by: Jesse Barnes <jbarnes at virtuousgeek.org>
>
> 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;
> +
> + 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
> _______________________________________________
> xorg-devel mailing list
> xorg-devel at lists.x.org
> http://lists.x.org/mailman/listinfo/xorg-devel
>
More information about the xorg-devel
mailing list