diff options
author | Jesse Barnes <jbarnes@virtuousgeek.org> | 2010-01-25 09:21:51 -0800 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2010-01-27 14:35:18 -0800 |
commit | 711e26466ae04ae93ff4c48d377d83d68a6320e9 (patch) | |
tree | 2df99669c3474436d16904e631ab525929948feb | |
parent | b68f0204a2e4fa9d8884cbdd84b6a5df21d6b36e (diff) |
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>
-rw-r--r-- | hw/xfree86/dri2/dri2.c | 42 |
1 files changed, 27 insertions, 15 deletions
diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c index 3d0fa75ec..587a9285a 100644 --- a/hw/xfree86/dri2/dri2.c +++ b/hw/xfree86/dri2/dri2.c @@ -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 |