[PATCH weston 4/8] libweston: Make weston_seat release safe

Alexandros Frantzis alexandros.frantzis at collabora.com
Fri Jan 26 16:47:58 UTC 2018


Ensure the server can safely handle client requests for wl_seat resource
that have become inert due to weston_seat object release and subsequent
destruction.

The clean-up involves, among other things, unsetting the destroyed
weston_seat object from the user data of wl_seat resources, and handling
this NULL user data case where required.

Signed-off-by: Alexandros Frantzis <alexandros.frantzis at collabora.com>
---
 libweston/input.c | 45 +++++++++++++++++++++++++++++++++++----------
 1 file changed, 35 insertions(+), 10 deletions(-)

diff --git a/libweston/input.c b/libweston/input.c
index 48bcc55c..e4daa56b 100644
--- a/libweston/input.c
+++ b/libweston/input.c
@@ -2412,6 +2412,13 @@ seat_get_pointer(struct wl_client *client, struct wl_resource *resource,
 		 uint32_t id)
 {
 	struct weston_seat *seat = wl_resource_get_user_data(resource);
+	struct weston_pointer *pointer;
+	struct wl_resource *cr;
+	struct weston_pointer_client *pointer_client;
+
+	if (!seat)
+		return;
+
 	/* We use the pointer_state directly, which means we'll
 	 * give a wl_pointer if the seat has ever had one - even though
 	 * the spec explicitly states that this request only takes effect
@@ -2420,10 +2427,7 @@ seat_get_pointer(struct wl_client *client, struct wl_resource *resource,
 	 * This prevents a race between the compositor sending new
 	 * capabilities and the client trying to use the old ones.
 	 */
-	struct weston_pointer *pointer = seat->pointer_state;
-	struct wl_resource *cr;
-	struct weston_pointer_client *pointer_client;
-
+	pointer = seat->pointer_state;
 	if (!pointer)
 		return;
 
@@ -2499,6 +2503,12 @@ seat_get_keyboard(struct wl_client *client, struct wl_resource *resource,
 		  uint32_t id)
 {
 	struct weston_seat *seat = wl_resource_get_user_data(resource);
+	struct weston_keyboard *keyboard;
+	struct wl_resource *cr;
+
+	if (!seat)
+		return;
+
 	/* We use the keyboard_state directly, which means we'll
 	 * give a wl_keyboard if the seat has ever had one - even though
 	 * the spec explicitly states that this request only takes effect
@@ -2507,9 +2517,7 @@ seat_get_keyboard(struct wl_client *client, struct wl_resource *resource,
 	 * This prevents a race between the compositor sending new
 	 * capabilities and the client trying to use the old ones.
 	 */
-	struct weston_keyboard *keyboard = seat->keyboard_state;
-	struct wl_resource *cr;
-
+	keyboard = seat->keyboard_state;
 	if (!keyboard)
 		return;
 
@@ -2579,6 +2587,12 @@ seat_get_touch(struct wl_client *client, struct wl_resource *resource,
 	       uint32_t id)
 {
 	struct weston_seat *seat = wl_resource_get_user_data(resource);
+	struct weston_touch *touch;
+	struct wl_resource *cr;
+
+	if (!seat)
+		return;
+
 	/* We use the touch_state directly, which means we'll
 	 * give a wl_touch if the seat has ever had one - even though
 	 * the spec explicitly states that this request only takes effect
@@ -2587,9 +2601,7 @@ seat_get_touch(struct wl_client *client, struct wl_resource *resource,
 	 * This prevents a race between the compositor sending new
 	 * capabilities and the client trying to use the old ones.
 	 */
-	struct weston_touch *touch = seat->touch_state;
-	struct wl_resource *cr;
-
+	touch = seat->touch_state;
 	if (!touch)
 		return;
 
@@ -3087,6 +3099,19 @@ weston_seat_init(struct weston_seat *seat, struct weston_compositor *ec,
 WL_EXPORT void
 weston_seat_release(struct weston_seat *seat)
 {
+	struct wl_resource *resource;
+
+	wl_resource_for_each(resource, &seat->base_resource_list) {
+		wl_resource_set_user_data(resource, NULL);
+	}
+
+	wl_resource_for_each(resource, &seat->drag_resource_list) {
+		wl_resource_set_user_data(resource, NULL);
+	}
+
+	wl_list_remove(&seat->base_resource_list);
+	wl_list_remove(&seat->drag_resource_list);
+
 	wl_list_remove(&seat->link);
 
 	if (seat->saved_kbd_focus)
-- 
2.14.1



More information about the wayland-devel mailing list