[PATCH weston] xdg-shell: Add NULL checks for resources that may have gone away.

Dima Ryazanov dima at gmail.com
Sun Dec 4 05:21:44 UTC 2016


This should fix some (fairly rare) crashes where the client goes away at exactly
the wrong moment, e.g.:
- Weston sends a message to the client
- Message causes the client to crash for whatever reason
- Weston keeps processing the remaining requests from the now dead client

(I've only seen it happen once, while stepping through Weston's code in gdb, but
seems like the right thing to fix.)

Signed-off-by: Dima Ryazanov <dima at gmail.com>
---
 libweston-desktop/xdg-shell-v6.c | 141 ++++++++++++++++++++++++++++-----------
 1 file changed, 101 insertions(+), 40 deletions(-)

diff --git a/libweston-desktop/xdg-shell-v6.c b/libweston-desktop/xdg-shell-v6.c
index 7d0bd8e..30f6d82 100644
--- a/libweston-desktop/xdg-shell-v6.c
+++ b/libweston-desktop/xdg-shell-v6.c
@@ -302,10 +302,14 @@ weston_desktop_xdg_toplevel_protocol_set_parent(struct wl_client *wl_client,
 {
 	struct weston_desktop_surface *dsurface =
 		wl_resource_get_user_data(resource);
-	struct weston_desktop_xdg_toplevel *toplevel =
-		weston_desktop_surface_get_implementation_data(dsurface);
+	struct weston_desktop_xdg_toplevel *toplevel;
 	struct weston_desktop_surface *parent = NULL;
 
+	if (!dsurface)
+		return;
+
+	toplevel = weston_desktop_surface_get_implementation_data(dsurface);
+
 	if (parent_resource != NULL)
 		parent = wl_resource_get_user_data(parent_resource);
 
@@ -346,8 +350,12 @@ weston_desktop_xdg_toplevel_protocol_show_window_menu(struct wl_client *wl_clien
 		wl_resource_get_user_data(resource);
 	struct weston_seat *seat =
 		wl_resource_get_user_data(seat_resource);
-	struct weston_desktop_xdg_toplevel *toplevel =
-		weston_desktop_surface_get_implementation_data(dsurface);
+	struct weston_desktop_xdg_toplevel *toplevel;
+
+	if (!dsurface)
+		return;
+
+	toplevel = weston_desktop_surface_get_implementation_data(dsurface);
 
 	if (!toplevel->base.configured) {
 		wl_resource_post_error(toplevel->resource,
@@ -370,8 +378,12 @@ weston_desktop_xdg_toplevel_protocol_move(struct wl_client *wl_client,
 		wl_resource_get_user_data(resource);
 	struct weston_seat *seat =
 		wl_resource_get_user_data(seat_resource);
-	struct weston_desktop_xdg_toplevel *toplevel =
-		weston_desktop_surface_get_implementation_data(dsurface);
+	struct weston_desktop_xdg_toplevel *toplevel;
+
+	if (!dsurface)
+		return;
+
+	toplevel = weston_desktop_surface_get_implementation_data(dsurface);
 
 	if (!toplevel->base.configured) {
 		wl_resource_post_error(toplevel->resource,
@@ -394,11 +406,15 @@ weston_desktop_xdg_toplevel_protocol_resize(struct wl_client *wl_client,
 		wl_resource_get_user_data(resource);
 	struct weston_seat *seat =
 		wl_resource_get_user_data(seat_resource);
-	struct weston_desktop_xdg_toplevel *toplevel =
-		weston_desktop_surface_get_implementation_data(dsurface);
+	struct weston_desktop_xdg_toplevel *toplevel;
 	enum weston_desktop_surface_edge surf_edges =
 		(enum weston_desktop_surface_edge) edges;
 
+	if (!dsurface)
+		return;
+
+	toplevel = weston_desktop_surface_get_implementation_data(dsurface);
+
 	if (!toplevel->base.configured) {
 		wl_resource_post_error(toplevel->resource,
 				       ZXDG_SURFACE_V6_ERROR_NOT_CONSTRUCTED,
@@ -423,9 +439,12 @@ weston_desktop_xdg_toplevel_protocol_set_min_size(struct wl_client *wl_client,
 {
 	struct weston_desktop_surface *dsurface =
 		wl_resource_get_user_data(resource);
-	struct weston_desktop_xdg_toplevel *toplevel =
-		weston_desktop_surface_get_implementation_data(dsurface);
+	struct weston_desktop_xdg_toplevel *toplevel;
 
+	if (!dsurface)
+		return;
+
+	toplevel = weston_desktop_surface_get_implementation_data(dsurface);
 	toplevel->next_min_size.width = width;
 	toplevel->next_min_size.height = height;
 }
@@ -437,9 +456,12 @@ weston_desktop_xdg_toplevel_protocol_set_max_size(struct wl_client *wl_client,
 {
 	struct weston_desktop_surface *dsurface =
 		wl_resource_get_user_data(resource);
-	struct weston_desktop_xdg_toplevel *toplevel =
-		weston_desktop_surface_get_implementation_data(dsurface);
+	struct weston_desktop_xdg_toplevel *toplevel;
+
+	if (!dsurface)
+		return;
 
+	toplevel = weston_desktop_surface_get_implementation_data(dsurface);
 	toplevel->next_max_size.width = width;
 	toplevel->next_max_size.height = height;
 }
@@ -450,9 +472,12 @@ weston_desktop_xdg_toplevel_protocol_set_maximized(struct wl_client *wl_client,
 {
 	struct weston_desktop_surface *dsurface =
 		wl_resource_get_user_data(resource);
-	struct weston_desktop_xdg_toplevel *toplevel =
-		weston_desktop_surface_get_implementation_data(dsurface);
+	struct weston_desktop_xdg_toplevel *toplevel;
 
+	if (!dsurface)
+		return;
+
+	toplevel = weston_desktop_surface_get_implementation_data(dsurface);
 	weston_desktop_xdg_toplevel_ensure_added(toplevel);
 	weston_desktop_api_maximized_requested(toplevel->base.desktop, dsurface, true);
 }
@@ -463,9 +488,12 @@ weston_desktop_xdg_toplevel_protocol_unset_maximized(struct wl_client *wl_client
 {
 	struct weston_desktop_surface *dsurface =
 		wl_resource_get_user_data(resource);
-	struct weston_desktop_xdg_toplevel *toplevel =
-		weston_desktop_surface_get_implementation_data(dsurface);
+	struct weston_desktop_xdg_toplevel *toplevel;
+
+	if (!dsurface)
+		return;
 
+	toplevel = weston_desktop_surface_get_implementation_data(dsurface);
 	weston_desktop_xdg_toplevel_ensure_added(toplevel);
 	weston_desktop_api_maximized_requested(toplevel->base.desktop, dsurface, false);
 }
@@ -477,10 +505,14 @@ weston_desktop_xdg_toplevel_protocol_set_fullscreen(struct wl_client *wl_client,
 {
 	struct weston_desktop_surface *dsurface =
 		wl_resource_get_user_data(resource);
-	struct weston_desktop_xdg_toplevel *toplevel =
-		weston_desktop_surface_get_implementation_data(dsurface);
+	struct weston_desktop_xdg_toplevel *toplevel;
 	struct weston_output *output = NULL;
 
+	if (!dsurface)
+		return;
+
+	toplevel = weston_desktop_surface_get_implementation_data(dsurface);
+
 	if (output_resource != NULL)
 		output = wl_resource_get_user_data(output_resource);
 
@@ -495,9 +527,12 @@ weston_desktop_xdg_toplevel_protocol_unset_fullscreen(struct wl_client *wl_clien
 {
 	struct weston_desktop_surface *dsurface =
 		wl_resource_get_user_data(resource);
-	struct weston_desktop_xdg_toplevel *toplevel =
-		weston_desktop_surface_get_implementation_data(dsurface);
+	struct weston_desktop_xdg_toplevel *toplevel;
+
+	if (!dsurface)
+		return;
 
+	toplevel = weston_desktop_surface_get_implementation_data(dsurface);
 	weston_desktop_xdg_toplevel_ensure_added(toplevel);
 	weston_desktop_api_fullscreen_requested(toplevel->base.desktop, dsurface,
 						false, NULL);
@@ -509,9 +544,12 @@ weston_desktop_xdg_toplevel_protocol_set_minimized(struct wl_client *wl_client,
 {
 	struct weston_desktop_surface *dsurface =
 		wl_resource_get_user_data(resource);
-	struct weston_desktop_xdg_toplevel *toplevel =
-		weston_desktop_surface_get_implementation_data(dsurface);
+	struct weston_desktop_xdg_toplevel *toplevel;
 
+	if (!dsurface)
+		return;
+
+	toplevel = weston_desktop_surface_get_implementation_data(dsurface);
 	weston_desktop_xdg_toplevel_ensure_added(toplevel);
 	weston_desktop_api_minimized_requested(toplevel->base.desktop, dsurface);
 }
@@ -737,12 +775,19 @@ weston_desktop_xdg_popup_protocol_grab(struct wl_client *wl_client,
 {
 	struct weston_desktop_surface *dsurface =
 		wl_resource_get_user_data(resource);
-	struct weston_desktop_xdg_popup *popup =
-		weston_desktop_surface_get_implementation_data(dsurface);
+	struct weston_desktop_xdg_popup *popup;
 	struct weston_seat *wseat = wl_resource_get_user_data(seat_resource);
-	struct weston_desktop_seat *seat = weston_desktop_seat_from_seat(wseat);
+	struct weston_desktop_seat *seat;
 	struct weston_desktop_surface *topmost;
-	bool parent_is_toplevel =
+	bool parent_is_toplevel;
+
+	if (!dsurface || !wseat)
+		return;
+
+	seat = weston_desktop_seat_from_seat(wseat);
+	popup = weston_desktop_surface_get_implementation_data(dsurface);
+
+	parent_is_toplevel =
 		popup->parent->role == WESTON_DESKTOP_XDG_SURFACE_ROLE_TOPLEVEL;
 
 	if (popup->committed) {
@@ -891,10 +936,14 @@ weston_desktop_xdg_surface_protocol_get_toplevel(struct wl_client *wl_client,
 {
 	struct weston_desktop_surface *dsurface =
 		wl_resource_get_user_data(resource);
-	struct weston_surface *wsurface =
-		weston_desktop_surface_get_surface(dsurface);
-	struct weston_desktop_xdg_toplevel *toplevel =
-		weston_desktop_surface_get_implementation_data(dsurface);
+	struct weston_surface *wsurface;
+	struct weston_desktop_xdg_toplevel *toplevel;
+
+	if (!dsurface)
+		return;
+
+	toplevel = weston_desktop_surface_get_implementation_data(dsurface);
+	wsurface = weston_desktop_surface_get_surface(dsurface);
 
 	if (weston_surface_set_role(wsurface, weston_desktop_xdg_toplevel_role,
 				    resource, ZXDG_SHELL_V6_ERROR_ROLE) < 0)
@@ -920,17 +969,21 @@ weston_desktop_xdg_surface_protocol_get_popup(struct wl_client *wl_client,
 {
 	struct weston_desktop_surface *dsurface =
 		wl_resource_get_user_data(resource);
-	struct weston_surface *wsurface =
-		weston_desktop_surface_get_surface(dsurface);
-	struct weston_desktop_xdg_popup *popup =
-		weston_desktop_surface_get_implementation_data(dsurface);
+	struct weston_surface *wsurface;
+	struct weston_desktop_xdg_popup *popup;
 	struct weston_desktop_surface *parent_surface =
 		wl_resource_get_user_data(parent_resource);
-	struct weston_desktop_xdg_surface *parent =
-		weston_desktop_surface_get_implementation_data(parent_surface);
+	struct weston_desktop_xdg_surface *parent;
 	struct weston_desktop_xdg_positioner *positioner =
 		wl_resource_get_user_data(positioner_resource);
 
+	if (!dsurface || !parent_surface || !positioner)
+		return;
+
+	wsurface = weston_desktop_surface_get_surface(dsurface);
+	popup =	weston_desktop_surface_get_implementation_data(dsurface);
+	parent = weston_desktop_surface_get_implementation_data(parent_surface);
+
 	/* Checking whether the size and anchor rect both have a positive size
 	 * is enough to verify both have been correctly set */
 	if (positioner->size.width == 0 || positioner->anchor_rect.width == 0) {
@@ -994,8 +1047,12 @@ weston_desktop_xdg_surface_protocol_set_window_geometry(struct wl_client *wl_cli
 {
 	struct weston_desktop_surface *dsurface =
 		wl_resource_get_user_data(resource);
-	struct weston_desktop_xdg_surface *surface =
-		weston_desktop_surface_get_implementation_data(dsurface);
+	struct weston_desktop_xdg_surface *surface;
+
+	if (!dsurface)
+		return;
+
+	surface = weston_desktop_surface_get_implementation_data(dsurface);
 
 	if (!weston_desktop_xdg_surface_check_role(surface))
 		return;
@@ -1014,8 +1071,12 @@ weston_desktop_xdg_surface_protocol_ack_configure(struct wl_client *wl_client,
 {
 	struct weston_desktop_surface *dsurface =
 		wl_resource_get_user_data(resource);
-	struct weston_desktop_xdg_surface *surface =
-		weston_desktop_surface_get_implementation_data(dsurface);
+	struct weston_desktop_xdg_surface *surface;
+
+	if (!dsurface)
+		return;
+
+	surface = weston_desktop_surface_get_implementation_data(dsurface);
 
 	if (!weston_desktop_xdg_surface_check_role(surface))
 		return;
-- 
2.9.3



More information about the wayland-devel mailing list