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>
This commit is contained in:
parent
a5bcc4f7b9
commit
e5a188cb91
|
@ -171,7 +171,8 @@ present_vblank_notify(present_vblank_ptr vblank, CARD8 kind, CARD8 mode, uint64_
|
||||||
{
|
{
|
||||||
int n;
|
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++) {
|
for (n = 0; n < vblank->num_notifies; n++) {
|
||||||
WindowPtr window = vblank->notifies[n].window;
|
WindowPtr window = vblank->notifies[n].window;
|
||||||
CARD32 serial = vblank->notifies[n].serial;
|
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
|
static void
|
||||||
present_flip_notify(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
|
present_flip_notify(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
|
||||||
{
|
{
|
||||||
WindowPtr window = vblank->window;
|
ScreenPtr screen = vblank->screen;
|
||||||
ScreenPtr screen = window->drawable.pScreen;
|
|
||||||
present_screen_priv_ptr screen_priv = present_screen_priv(screen);
|
present_screen_priv_ptr screen_priv = present_screen_priv(screen);
|
||||||
|
|
||||||
DebugPresent(("\tn %p %8lld: %08lx -> %08lx\n", vblank, vblank->target_msc,
|
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)
|
if (vblank->abort_flip)
|
||||||
present_unflip(screen);
|
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);
|
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);
|
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) {
|
if (vblank->flip && screen_priv->flip_pending == NULL && !screen_priv->unflip_event_id) {
|
||||||
|
|
||||||
|
|
|
@ -72,8 +72,6 @@ struct present_vblank {
|
||||||
Bool flip;
|
Bool flip;
|
||||||
Bool sync_flip;
|
Bool sync_flip;
|
||||||
Bool abort_flip;
|
Bool abort_flip;
|
||||||
|
|
||||||
Bool window_destroyed;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct present_screen_priv {
|
typedef struct present_screen_priv {
|
||||||
|
|
|
@ -92,7 +92,7 @@ present_clear_window_flip(WindowPtr window)
|
||||||
|
|
||||||
if (flip_pending && flip_pending->window == window) {
|
if (flip_pending && flip_pending->window == window) {
|
||||||
assert (flip_pending->abort_flip);
|
assert (flip_pending->abort_flip);
|
||||||
flip_pending->window_destroyed = TRUE;
|
flip_pending->window = NULL;
|
||||||
}
|
}
|
||||||
if (screen_priv->flip_window == window)
|
if (screen_priv->flip_window == window)
|
||||||
screen_priv->flip_window = NULL;
|
screen_priv->flip_window = NULL;
|
||||||
|
|
Loading…
Reference in New Issue