diff options
author | Keith Packard <keithp@keithp.com> | 2013-11-09 12:36:47 -0800 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2013-11-20 13:12:27 -0800 |
commit | e5a188cb919edee2e3a03054276bce0db02f7b62 (patch) | |
tree | b907abd2d81d8392b3e656f507ac5c710bb8b85e | |
parent | a5bcc4f7b9499caf8993f0a6ef96088553399ca3 (diff) |
present: Signal destroyed flip window with vblank->window == NULL
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@keithp.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
-rw-r--r-- | present/present.c | 11 | ||||
-rw-r--r-- | present/present_priv.h | 2 | ||||
-rw-r--r-- | present/present_screen.c | 2 |
3 files changed, 6 insertions, 9 deletions
diff --git a/present/present.c b/present/present.c index bfafa928e..67d7f6eee 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 a92b62a2d..40c88dd0b 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 50b2b2d23..2702cd6ca 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; |