libweston: Make weston_keyboard destruction safe
authorAlexandros Frantzis <alexandros.frantzis@collabora.com>
Fri, 26 Jan 2018 16:47:56 +0000 (18:47 +0200)
committerPekka Paalanen <pekka.paalanen@collabora.co.uk>
Thu, 1 Feb 2018 10:49:15 +0000 (12:49 +0200)
Ensure the server can safely handle client requests for wl_keyboard
resources that have become inert due to a weston_keyboard object
destruction.

This change involves, among other things, setting the weston_keyboard
object, instead of the weston_seat object, as the user data for
wl_keyboard resources.  Although this is not strictly required at the
moment (since no code is using the wl_keyboard user data), it makes the
code safer:

 * It makes more sense conceptually.
 * It is consistent with how wl_pointer resources are handled.
 * It allows us to clear the user data during weston_keyboard
   destruction, so other code can check whether the resource is inert.

Signed-off-by: Alexandros Frantzis <alexandros.frantzis@collabora.com>
Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
libweston/input.c

index 94a3423a9a008dcee5de7e5c7719ed79a16a478c..6db476f73e38e086a1eff1e189ad62b3fe8de77b 100644 (file)
@@ -1144,7 +1144,18 @@ weston_xkb_info_destroy(struct weston_xkb_info *xkb_info);
 WL_EXPORT void
 weston_keyboard_destroy(struct weston_keyboard *keyboard)
 {
-       /* XXX: What about keyboard->resource_list? */
+       struct wl_resource *resource;
+
+       wl_resource_for_each(resource, &keyboard->resource_list) {
+               wl_resource_set_user_data(resource, NULL);
+       }
+
+       wl_resource_for_each(resource, &keyboard->focus_resource_list) {
+               wl_resource_set_user_data(resource, NULL);
+       }
+
+       wl_list_remove(&keyboard->resource_list);
+       wl_list_remove(&keyboard->focus_resource_list);
 
        xkb_state_unref(keyboard->xkb_state.state);
        if (keyboard->xkb_info)
@@ -2479,7 +2490,7 @@ seat_get_keyboard(struct wl_client *client, struct wl_resource *resource,
         * focused */
        wl_list_insert(&keyboard->resource_list, wl_resource_get_link(cr));
        wl_resource_set_implementation(cr, &keyboard_interface,
-                                      seat, unbind_resource);
+                                      keyboard, unbind_resource);
 
        if (wl_resource_get_version(cr) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION) {
                wl_keyboard_send_repeat_info(cr,