aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDaniel Stone <daniels@collabora.com>2022-07-21 11:07:04 +0100
committerDaniel Stone <daniels@collabora.com>2022-10-20 11:26:22 +0000
commit51d788de5b5b3443fa1ca71115d16a53281c5ed9 (patch)
tree8ff51dd8452cbc0d33745bf8c71739c0492eade7 /src
parenttests: Use bool for client test (diff)
downloadwayland-51d788de5b5b3443fa1ca71115d16a53281c5ed9.tar
wayland-51d788de5b5b3443fa1ca71115d16a53281c5ed9.tar.gz
wayland-51d788de5b5b3443fa1ca71115d16a53281c5ed9.tar.bz2
wayland-51d788de5b5b3443fa1ca71115d16a53281c5ed9.tar.lz
wayland-51d788de5b5b3443fa1ca71115d16a53281c5ed9.tar.xz
wayland-51d788de5b5b3443fa1ca71115d16a53281c5ed9.tar.zst
wayland-51d788de5b5b3443fa1ca71115d16a53281c5ed9.zip
wayland-server: Add wl_client_add_destroy_late_listener
A late-destroy listener for a client is called after all the client's resources have been destroyed and the destroy callbacks emitted. This lives in parallel to the existing client destroy listener, called immediately before the client's objects get destroyed. Signed-off-by: Daniel Stone <daniels@collabora.com> Fixes: wayland/wayland#207
Diffstat (limited to 'src')
-rw-r--r--src/wayland-server-core.h8
-rw-r--r--src/wayland-server.c42
2 files changed, 50 insertions, 0 deletions
diff --git a/src/wayland-server-core.h b/src/wayland-server-core.h
index 7a1375f..d9917a0 100644
--- a/src/wayland-server-core.h
+++ b/src/wayland-server-core.h
@@ -330,6 +330,14 @@ struct wl_listener *
wl_client_get_destroy_listener(struct wl_client *client,
wl_notify_func_t notify);
+void
+wl_client_add_destroy_late_listener(struct wl_client *client,
+ struct wl_listener *listener);
+
+struct wl_listener *
+wl_client_get_destroy_late_listener(struct wl_client *client,
+ wl_notify_func_t notify);
+
struct wl_resource *
wl_client_get_object(struct wl_client *client, uint32_t id);
diff --git a/src/wayland-server.c b/src/wayland-server.c
index 617d637..ee53f76 100644
--- a/src/wayland-server.c
+++ b/src/wayland-server.c
@@ -79,6 +79,7 @@ struct wl_client {
struct wl_list link;
struct wl_map objects;
struct wl_priv_signal destroy_signal;
+ struct wl_priv_signal destroy_late_signal;
pid_t pid;
uid_t uid;
gid_t gid;
@@ -547,6 +548,7 @@ wl_client_create(struct wl_display *display, int fd)
goto err_map;
wl_priv_signal_init(&client->destroy_signal);
+ wl_priv_signal_init(&client->destroy_late_signal);
if (bind_display(client, display) < 0)
goto err_map;
@@ -864,6 +866,17 @@ wl_resource_get_class(struct wl_resource *resource)
return resource->object.interface->name;
}
+/**
+ * Add a listener to be called at the beginning of wl_client destruction
+ *
+ * The listener provided will be called when wl_client destroy has begun,
+ * before any of that client's resources have been destroyed.
+ *
+ * There is no requirement to remove the link of the wl_listener when the
+ * signal is emitted.
+ *
+ * \memberof wl_client
+ */
WL_EXPORT void
wl_client_add_destroy_listener(struct wl_client *client,
struct wl_listener *listener)
@@ -878,6 +891,32 @@ wl_client_get_destroy_listener(struct wl_client *client,
return wl_priv_signal_get(&client->destroy_signal, notify);
}
+/**
+ * Add a listener to be called at the end of wl_client destruction
+ *
+ * The listener provided will be called when wl_client destroy is nearly
+ * complete, after all of that client's resources have been destroyed.
+ *
+ * There is no requirement to remove the link of the wl_listener when the
+ * signal is emitted.
+ *
+ * \memberof wl_client
+ * \since 1.22.0
+ */
+WL_EXPORT void
+wl_client_add_destroy_late_listener(struct wl_client *client,
+ struct wl_listener *listener)
+{
+ wl_priv_signal_add(&client->destroy_late_signal, listener);
+}
+
+WL_EXPORT struct wl_listener *
+wl_client_get_destroy_late_listener(struct wl_client *client,
+ wl_notify_func_t notify)
+{
+ return wl_priv_signal_get(&client->destroy_late_signal, notify);
+}
+
WL_EXPORT void
wl_client_destroy(struct wl_client *client)
{
@@ -890,6 +929,9 @@ wl_client_destroy(struct wl_client *client)
wl_map_release(&client->objects);
wl_event_source_remove(client->source);
close(wl_connection_destroy(client->connection));
+
+ wl_priv_signal_final_emit(&client->destroy_late_signal, client);
+
wl_list_remove(&client->link);
wl_list_remove(&client->resource_created_signal.listener_list);
free(client);