[PATCH 3/3] present: Signal destroyed flip window with vblank->window == NULL

Keith Packard keithp at keithp.com
Mon Nov 11 16:12:32 PST 2013


This eliminates dereferencing freed window pointers when there is a
flip for that window in progress. The flip will complete, and then
immediately get undone (as we can't stop an in-progress flip).

Remove the vblank->window_destroyed field as we can signal this with
vblank->window == NULL instead.

Change check to vblank->window == NULL in:

	present_flip_notify

Add check for vblank->window == NULL in:
	present_vblank_notify
	present_execute

present_flip_notify was also using vblank->window->drawable.pScreen,
so stop doing that and use vblank->screen instead.

Signed-off-by: Keith Packard <keithp at keithp.com>
---
 present/present.c        | 11 +++++------
 present/present_priv.h   |  2 --
 present/present_screen.c |  2 +-
 3 files changed, 6 insertions(+), 9 deletions(-)

diff --git a/present/present.c b/present/present.c
index bfafa92..67d7f6e 100644
--- a/present/present.c
+++ b/present/present.c
@@ -171,7 +171,8 @@ present_vblank_notify(present_vblank_ptr vblank, CARD8 kind, CARD8 mode, uint64_
 {
     int         n;
 
-    present_send_complete_notify(vblank->window, kind, mode, vblank->serial, ust, crtc_msc - vblank->msc_offset);
+    if (vblank->window)
+        present_send_complete_notify(vblank->window, kind, mode, vblank->serial, ust, crtc_msc - vblank->msc_offset);
     for (n = 0; n < vblank->num_notifies; n++) {
         WindowPtr   window = vblank->notifies[n].window;
         CARD32      serial = vblank->notifies[n].serial;
@@ -336,8 +337,7 @@ present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc);
 static void
 present_flip_notify(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
 {
-    WindowPtr                   window = vblank->window;
-    ScreenPtr                   screen = window->drawable.pScreen;
+    ScreenPtr                   screen = vblank->screen;
     present_screen_priv_ptr     screen_priv = present_screen_priv(screen);
 
     DebugPresent(("\tn %p %8lld: %08lx -> %08lx\n", vblank, vblank->target_msc,
@@ -363,8 +363,7 @@ present_flip_notify(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
     if (vblank->abort_flip)
         present_unflip(screen);
 
-    if (!vblank->window_destroyed)
-        present_vblank_notify(vblank, PresentCompleteKindPixmap, PresentCompleteModeFlip, ust, crtc_msc);
+    present_vblank_notify(vblank, PresentCompleteKindPixmap, PresentCompleteModeFlip, ust, crtc_msc);
     present_vblank_destroy(vblank);
 }
 
@@ -474,7 +473,7 @@ present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
     }
 
     xorg_list_del(&vblank->event_queue);
-    if (vblank->pixmap) {
+    if (vblank->pixmap && vblank->window) {
 
         if (vblank->flip && screen_priv->flip_pending == NULL && !screen_priv->unflip_event_id) {
 
diff --git a/present/present_priv.h b/present/present_priv.h
index a92b62a..40c88dd 100644
--- a/present/present_priv.h
+++ b/present/present_priv.h
@@ -72,8 +72,6 @@ struct present_vblank {
     Bool                flip;
     Bool                sync_flip;
     Bool                abort_flip;
-
-    Bool                window_destroyed;
 };
 
 typedef struct present_screen_priv {
diff --git a/present/present_screen.c b/present/present_screen.c
index 50b2b2d..2702cd6 100644
--- a/present/present_screen.c
+++ b/present/present_screen.c
@@ -92,7 +92,7 @@ present_clear_window_flip(WindowPtr window)
 
     if (flip_pending && flip_pending->window == window) {
         assert (flip_pending->abort_flip);
-        flip_pending->window_destroyed = TRUE;
+        flip_pending->window = NULL;
     }
     if (screen_priv->flip_window == window)
         screen_priv->flip_window = NULL;
-- 
1.8.4.2



More information about the xorg-devel mailing list