summaryrefslogtreecommitdiff
path: root/src/radeon_dri2.c
diff options
context:
space:
mode:
authorMichel Dänzer <michel.daenzer@amd.com>2012-03-06 15:52:40 +0100
committerMichel Dänzer <michel@daenzer.net>2012-03-06 15:52:40 +0100
commit355dc4295912c153f5333421594fa90aa119a056 (patch)
treef54b5723bb82ec961a3c88daef614d26aed99d4e /src/radeon_dri2.c
parentfe51469b2e02e4d565050bab077985270fb58a9b (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>
Diffstat (limited to 'src/radeon_dri2.c')
-rw-r--r--src/radeon_dri2.c41
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);
}