[PATCH weston] clients: add global_remove handler stubs

Pekka Paalanen ppaalanen at gmail.com
Tue Jan 22 04:53:55 PST 2013


All the clients here were missing the global_remove handler. Because
window.c did not have it, weston-desktop-shell and weston-keyboard
segfaulted on compositor exit, as they received some
wl_registry.global_remove events.

Add more or less stub global_remove handlers, so that clients do not
crash on such events. Toytoolkit and all applications would need a lot
more code to properly handle the global object removal.

Signed-off-by: Pekka Paalanen <ppaalanen at gmail.com>

---

It is supposed to go like this:
1. server decides to remove a global object
2. server broadcasts wl_registry.global_remove
3. a client handles wl_registry.global_remove by destroying the object
   it got by binding to the global.

...all clients have destroyed their objects.
?. server actually destroys the global and frees its name

But how does the server know to destroy the global, when most (all?) of
our globals do not have a destroy request?
---
 clients/screenshot.c       |  9 ++++++++-
 clients/simple-egl.c       |  9 ++++++++-
 clients/simple-shm.c       |  9 ++++++++-
 clients/simple-touch.c     |  8 +++++++-
 clients/weston-info.c      |  8 +++++++-
 clients/weston-simple-im.c |  9 ++++++++-
 clients/window.c           | 24 +++++++++++++++++++++++-
 7 files changed, 69 insertions(+), 7 deletions(-)

diff --git a/clients/screenshot.c b/clients/screenshot.c
index 8681a41..efacfed 100644
--- a/clients/screenshot.c
+++ b/clients/screenshot.c
@@ -128,8 +128,15 @@ handle_global(void *data, struct wl_registry *registry,
 	}
 }
 
+static void
+handle_global_remove(void *data, struct wl_registry *registry, uint32_t name)
+{
+	/* XXX: unimplemented */
+}
+
 static const struct wl_registry_listener registry_listener = {
-	handle_global
+	handle_global,
+	handle_global_remove
 };
 
 static struct wl_buffer *
diff --git a/clients/simple-egl.c b/clients/simple-egl.c
index b84fae3..26ebe5c 100644
--- a/clients/simple-egl.c
+++ b/clients/simple-egl.c
@@ -588,8 +588,15 @@ registry_handle_global(void *data, struct wl_registry *registry,
 	}
 }
 
+static void
+registry_handle_global_remove(void *data, struct wl_registry *registry,
+			      uint32_t name)
+{
+}
+
 static const struct wl_registry_listener registry_listener = {
-	registry_handle_global
+	registry_handle_global,
+	registry_handle_global_remove
 };
 
 static void
diff --git a/clients/simple-shm.c b/clients/simple-shm.c
index 831f9a4..c2eda61 100644
--- a/clients/simple-shm.c
+++ b/clients/simple-shm.c
@@ -322,8 +322,15 @@ registry_handle_global(void *data, struct wl_registry *registry,
 	}
 }
 
+static void
+registry_handle_global_remove(void *data, struct wl_registry *registry,
+			      uint32_t name)
+{
+}
+
 static const struct wl_registry_listener registry_listener = {
-	registry_handle_global
+	registry_handle_global,
+	registry_handle_global_remove
 };
 
 static struct display *
diff --git a/clients/simple-touch.c b/clients/simple-touch.c
index cbe3877..b8473f1 100644
--- a/clients/simple-touch.c
+++ b/clients/simple-touch.c
@@ -264,8 +264,14 @@ handle_global(void *data, struct wl_registry *registry,
 	}
 }
 
+static void
+handle_global_remove(void *data, struct wl_registry *registry, uint32_t name)
+{
+}
+
 static const struct wl_registry_listener registry_listener = {
-	handle_global
+	handle_global,
+	handle_global_remove
 };
 
 static struct touch *
diff --git a/clients/weston-info.c b/clients/weston-info.c
index edd826e..a5db02a 100644
--- a/clients/weston-info.c
+++ b/clients/weston-info.c
@@ -387,8 +387,14 @@ global_handler(void *data, struct wl_registry *registry, uint32_t id,
 		add_global_info(info, id, interface, version);
 }
 
+static void
+global_remove_handler(void *data, struct wl_registry *registry, uint32_t name)
+{
+}
+
 static const struct wl_registry_listener registry_listener = {
-	global_handler
+	global_handler,
+	global_remove_handler
 };
 
 static void
diff --git a/clients/weston-simple-im.c b/clients/weston-simple-im.c
index 36af095..46887e8 100644
--- a/clients/weston-simple-im.c
+++ b/clients/weston-simple-im.c
@@ -300,8 +300,15 @@ registry_handle_global(void *data, struct wl_registry *registry,
 	}
 }
 
+static void
+registry_handle_global_remove(void *data, struct wl_registry *registry,
+			      uint32_t name)
+{
+}
+
 static const struct wl_registry_listener registry_listener = {
-	registry_handle_global
+	registry_handle_global,
+	registry_handle_global_remove
 };
 
 static int
diff --git a/clients/window.c b/clients/window.c
index 0701981..799926c 100644
--- a/clients/window.c
+++ b/clients/window.c
@@ -4079,6 +4079,27 @@ registry_handle_global(void *data, struct wl_registry *registry, uint32_t id,
 		d->global_handler(d, id, interface, version, d->user_data);
 }
 
+static void
+registry_handle_global_remove(void *data, struct wl_registry *registry,
+			      uint32_t name)
+{
+	struct display *d = data;
+	struct global *global;
+	struct global *tmp;
+
+	wl_list_for_each_safe(global, tmp, &d->global_list, link) {
+		if (global->name != name)
+			continue;
+
+		/* XXX: Should destroy bound globals, and call
+		 * the counterpart of display::global_handler
+		 */
+		wl_list_remove(&global->link);
+		free(global->interface);
+		free(global);
+	}
+}
+
 void *
 display_bind(struct display *display, uint32_t name,
 	     const struct wl_interface *interface, uint32_t version)
@@ -4087,7 +4108,8 @@ display_bind(struct display *display, uint32_t name,
 }
 
 static const struct wl_registry_listener registry_listener = {
-	registry_handle_global
+	registry_handle_global,
+	registry_handle_global_remove
 };
 
 #ifdef HAVE_CAIRO_EGL
-- 
1.7.12.4



More information about the wayland-devel mailing list