mirror of
https://gitlab.freedesktop.org/wayland/wayland.git
synced 2026-04-05 07:15:46 -04:00
server: add wl_display_destroy_clients()
Bug [1] reported that wl_display_destroy() doesn't destroy clients, so client socket file descriptors are being kept open until the compositor process exits. Patch [2] proposed to destroy clients in wl_display_destroy(). The patch was not accepted because doing so changes the ABI. Thus, a new wl_display_destroy_clients() function is added in this patch. It should be called by compositors right before wl_display_destroy(). [1] https://bugs.freedesktop.org/show_bug.cgi?id=99142 [2] https://patchwork.freedesktop.org/patch/128832/ Signed-off-by: Simon Ser <contact@emersion.fr> Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Acked-by: Daniel Stone <daniels@collabora.com>
This commit is contained in:
parent
ef48ff21f0
commit
bf7cc68053
2 changed files with 41 additions and 0 deletions
|
|
@ -214,6 +214,9 @@ wl_display_run(struct wl_display *display);
|
||||||
void
|
void
|
||||||
wl_display_flush_clients(struct wl_display *display);
|
wl_display_flush_clients(struct wl_display *display);
|
||||||
|
|
||||||
|
void
|
||||||
|
wl_display_destroy_clients(struct wl_display *display);
|
||||||
|
|
||||||
struct wl_client;
|
struct wl_client;
|
||||||
|
|
||||||
typedef void (*wl_global_bind_func_t)(struct wl_client *client, void *data,
|
typedef void (*wl_global_bind_func_t)(struct wl_client *client, void *data,
|
||||||
|
|
|
||||||
|
|
@ -1279,6 +1279,44 @@ wl_display_flush_clients(struct wl_display *display)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Destroy all clients connected to the display
|
||||||
|
*
|
||||||
|
* \param display The display object
|
||||||
|
*
|
||||||
|
* This function should be called right before wl_display_destroy() to ensure
|
||||||
|
* all client resources are closed properly. Destroying a client from within
|
||||||
|
* wl_display_destroy_clients() is safe, but creating one will leak resources
|
||||||
|
* and raise a warning.
|
||||||
|
*
|
||||||
|
* \memberof wl_display
|
||||||
|
*/
|
||||||
|
WL_EXPORT void
|
||||||
|
wl_display_destroy_clients(struct wl_display *display)
|
||||||
|
{
|
||||||
|
struct wl_list tmp_client_list, *pos;
|
||||||
|
struct wl_client *client;
|
||||||
|
|
||||||
|
/* Move the whole client list to a temporary head because some new clients
|
||||||
|
* might be added to the original head. */
|
||||||
|
wl_list_init(&tmp_client_list);
|
||||||
|
wl_list_insert_list(&tmp_client_list, &display->client_list);
|
||||||
|
wl_list_init(&display->client_list);
|
||||||
|
|
||||||
|
/* wl_list_for_each_safe isn't enough here: it fails if the next client is
|
||||||
|
* destroyed by the destroy handler of the current one. */
|
||||||
|
while (!wl_list_empty(&tmp_client_list)) {
|
||||||
|
pos = tmp_client_list.next;
|
||||||
|
client = wl_container_of(pos, client, link);
|
||||||
|
|
||||||
|
wl_client_destroy(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!wl_list_empty(&display->client_list)) {
|
||||||
|
wl_log("wl_display_destroy_clients: cannot destroy all clients because "
|
||||||
|
"new ones were created by destroy callbacks\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
socket_data(int fd, uint32_t mask, void *data)
|
socket_data(int fd, uint32_t mask, void *data)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue