diff options
author | Michel Dänzer <michel.daenzer@amd.com> | 2012-03-06 15:52:40 +0100 |
---|---|---|
committer | Michel Dänzer <michel@daenzer.net> | 2012-03-06 15:52:40 +0100 |
commit | 355dc4295912c153f5333421594fa90aa119a056 (patch) | |
tree | f54b5723bb82ec961a3c88daef614d26aed99d4e | |
parent | fe51469b2e02e4d565050bab077985270fb58a9b (diff) |
DRI2: Unreference buffers immediately when event wait info is invalidated.
Deferring this could result in trying to unreference buffers from a previous
server generation, i.e. accessing freed memory.
Signed-off-by: Michel Dänzer <michel.daenzer@amd.com>
Tested-by: Christian König <Christian.koenig@amd.com>
-rw-r--r-- | src/radeon_dri2.c | 41 |
1 files changed, 22 insertions, 19 deletions
diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c index cf905a11..8bd3f667 100644 --- a/src/radeon_dri2.c +++ b/src/radeon_dri2.c @@ -571,6 +571,22 @@ ListDelDRI2ClientEvents(ClientPtr client, struct xorg_list *entry) } static void +radeon_dri2_ref_buffer(BufferPtr buffer) +{ + struct dri2_buffer_priv *private = buffer->driverPrivate; + private->refcnt++; +} + +static void +radeon_dri2_unref_buffer(BufferPtr buffer) +{ + if (buffer) { + struct dri2_buffer_priv *private = buffer->driverPrivate; + radeon_dri2_destroy_buffer(&(private->pixmap->drawable), buffer); + } +} + +static void radeon_dri2_client_state_changed(CallbackListPtr *ClientStateCallback, pointer data, pointer calldata) { DRI2ClientEventsPtr pClientEventsPriv; @@ -591,6 +607,8 @@ radeon_dri2_client_state_changed(CallbackListPtr *ClientStateCallback, pointer d if (pClientEventsPriv) { xorg_list_for_each_entry(ref, &pClientEventsPriv->reference_list, link) { ref->valid = FALSE; + radeon_dri2_unref_buffer(ref->front); + radeon_dri2_unref_buffer(ref->back); } } break; @@ -599,22 +617,6 @@ radeon_dri2_client_state_changed(CallbackListPtr *ClientStateCallback, pointer d } } -static void -radeon_dri2_ref_buffer(BufferPtr buffer) -{ - struct dri2_buffer_priv *private = buffer->driverPrivate; - private->refcnt++; -} - -static void -radeon_dri2_unref_buffer(BufferPtr buffer) -{ - if (buffer) { - struct dri2_buffer_priv *private = buffer->driverPrivate; - radeon_dri2_destroy_buffer(&(private->pixmap->drawable), buffer); - } -} - static int radeon_dri2_drawable_crtc(DrawablePtr pDraw) { ScreenPtr pScreen = pDraw->pScreen; @@ -849,10 +851,11 @@ void radeon_dri2_frame_event_handler(unsigned int frame, unsigned int tv_sec, } cleanup: - radeon_dri2_unref_buffer(event->front); - radeon_dri2_unref_buffer(event->back); - if (event->valid) + if (event->valid) { + radeon_dri2_unref_buffer(event->front); + radeon_dri2_unref_buffer(event->back); ListDelDRI2ClientEvents(event->client, &event->link); + } free(event); } |