[weston] xwm: Don't remove the frame's window id from hash until the frame is destroyed

Submitted by Derek Foreman on April 2, 2015, 9:51 p.m.

Details

Message ID 1428011514-2202-1-git-send-email-derekf@osg.samsung.com
State Changes Requested
Delegated to: Derek Foreman
Headers show

Not browsing as part of any series.

Commit Message

Derek Foreman April 2, 2015, 9:51 p.m.
Previously when a client window was destroyed we destroyed its frame and
removed the frame's id from the window hash table.

If a window is created then destroyed very quickly a race exists - the
frame may receive a configure notify after its client window is already
gone.  This results in the window id lookup for the frame failing and
returning NULL, followed shortly by a crash when dereferencing the NULL
pointer.

Now we hold off on removing the frame's id from the hash table until we
actually receive a destroy notification for it.

This closes Bug 83994.
https://bugs.freedesktop.org/show_bug.cgi?id=83994

Signed-off-by: Derek Foreman <derekf@osg.samsung.com>
---
 xwayland/window-manager.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

Patch hide | download patch | download mbox

diff --git a/xwayland/window-manager.c b/xwayland/window-manager.c
index 145d940..d9248f9 100644
--- a/xwayland/window-manager.c
+++ b/xwayland/window-manager.c
@@ -1179,7 +1179,6 @@  weston_wm_window_destroy(struct weston_wm_window *window)
 		xcb_destroy_window(wm->conn, window->frame_id);
 		weston_wm_window_set_wm_state(window, ICCCM_WITHDRAWN_STATE);
 		weston_wm_window_set_virtual_desktop(window, -1);
-		hash_table_remove(wm->window_hash, window->frame_id);
 		window->frame_id = XCB_WINDOW_NONE;
 	}
 
@@ -1223,8 +1222,10 @@  weston_wm_handle_destroy_notify(struct weston_wm *wm, xcb_generic_event_t *event
 	       destroy_notify->event,
 	       our_resource(wm, destroy_notify->window) ? ", ours" : "");
 
-	if (our_resource(wm, destroy_notify->window))
+	if (our_resource(wm, destroy_notify->window)) {
+		hash_table_remove(wm->window_hash, destroy_notify->window);
 		return;
+	}
 
 	window = hash_table_lookup(wm->window_hash, destroy_notify->window);
 	weston_wm_window_destroy(window);