[PATCH weston 1/8] libweston: Make weston_pointer destruction safe
Alexandros Frantzis
alexandros.frantzis at collabora.com
Fri Jan 26 16:47:55 UTC 2018
Properly clean up all sub-objects (e.g., weston_pointer_client objects)
when a weston_pointer object is destroyed. The clean-up ensures that the
server is able to safely handle client requests to any associated
pointer resources, which, as a consenquence of a weston_pointer
destruction, have now become inert.
The clean-up involves, among other things, unsetting the destroyed
weston_pointer object from the user data of pointer resources, and
handling this NULL user data case where required.
Signed-off-by: Alexandros Frantzis <alexandros.frantzis at collabora.com>
---
libweston/input.c | 41 ++++++++++++++++++++++++++++++++++++-----
1 file changed, 36 insertions(+), 5 deletions(-)
diff --git a/libweston/input.c b/libweston/input.c
index 94a3423a..01f0d568 100644
--- a/libweston/input.c
+++ b/libweston/input.c
@@ -105,6 +105,19 @@ weston_pointer_client_create(struct wl_client *client)
static void
weston_pointer_client_destroy(struct weston_pointer_client *pointer_client)
{
+ struct wl_resource *resource;
+
+ wl_resource_for_each(resource, &pointer_client->pointer_resources) {
+ wl_resource_set_user_data(resource, NULL);
+ }
+
+ wl_resource_for_each(resource,
+ &pointer_client->relative_pointer_resources) {
+ wl_resource_set_user_data(resource, NULL);
+ }
+
+ wl_list_remove(&pointer_client->pointer_resources);
+ wl_list_remove(&pointer_client->relative_pointer_resources);
free(pointer_client);
}
@@ -170,11 +183,14 @@ unbind_pointer_client_resource(struct wl_resource *resource)
struct wl_client *client = wl_resource_get_client(resource);
struct weston_pointer_client *pointer_client;
- pointer_client = weston_pointer_get_pointer_client(pointer, client);
- assert(pointer_client);
-
wl_list_remove(wl_resource_get_link(resource));
- weston_pointer_cleanup_pointer_client(pointer, pointer_client);
+
+ if (pointer) {
+ pointer_client = weston_pointer_get_pointer_client(pointer,
+ client);
+ assert(pointer_client);
+ weston_pointer_cleanup_pointer_client(pointer, pointer_client);
+ }
}
static void unbind_resource(struct wl_resource *resource)
@@ -1092,12 +1108,18 @@ weston_pointer_create(struct weston_seat *seat)
WL_EXPORT void
weston_pointer_destroy(struct weston_pointer *pointer)
{
+ struct weston_pointer_client *pointer_client, *tmp;
+
wl_signal_emit(&pointer->destroy_signal, pointer);
if (pointer->sprite)
pointer_unmap_sprite(pointer);
- /* XXX: What about pointer->resource_list? */
+ wl_list_for_each_safe(pointer_client, tmp, &pointer->pointer_clients,
+ link) {
+ wl_list_remove(&pointer_client->link);
+ weston_pointer_client_destroy(pointer_client);
+ }
wl_list_remove(&pointer->focus_resource_listener.link);
wl_list_remove(&pointer->focus_view_listener.link);
@@ -2297,6 +2319,9 @@ pointer_set_cursor(struct wl_client *client, struct wl_resource *resource,
struct weston_pointer *pointer = wl_resource_get_user_data(resource);
struct weston_surface *surface = NULL;
+ if (!pointer)
+ return;
+
if (surface_resource)
surface = wl_resource_get_user_data(surface_resource);
@@ -3674,6 +3699,9 @@ pointer_constraints_lock_pointer(struct wl_client *client,
struct weston_region *region = region_resource ?
wl_resource_get_user_data(region_resource) : NULL;
+ if (!pointer)
+ return;
+
init_pointer_constraint(resource, id, surface, pointer, region, lifetime,
&zwp_locked_pointer_v1_interface,
&locked_pointer_interface,
@@ -4467,6 +4495,9 @@ pointer_constraints_confine_pointer(struct wl_client *client,
struct weston_region *region = region_resource ?
wl_resource_get_user_data(region_resource) : NULL;
+ if (!pointer)
+ return;
+
init_pointer_constraint(resource, id, surface, pointer, region, lifetime,
&zwp_confined_pointer_v1_interface,
&confined_pointer_interface,
--
2.14.1
More information about the wayland-devel
mailing list