From c09edeb2e730c3d6a7efb2fec439358dcec6911a Mon Sep 17 00:00:00 2001 From: Jihoon Kim Date: Fri, 19 May 2023 17:29:15 +0900 Subject: [PATCH] wayland-server: Fix hangup issue Change-Id: Ib175e0e239b63e6f6ec5a23d3960fe92deef0c14 Signed-off-by: Jihoon Kim --- src/wayland-server.c | 56 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 21 deletions(-) diff --git a/src/wayland-server.c b/src/wayland-server.c index b082d3e..4b32960 100644 --- a/src/wayland-server.c +++ b/src/wayland-server.c @@ -384,9 +384,6 @@ wl_client_connection_data(int fd, uint32_t mask, void *data) int len; int pid; - pthread_mutex_lock(&client->connection_mutex); - pthread_mutex_lock(&client->objects_mutex); - if (mask & WL_EVENT_HANGUP) { wl_log("Mask has hangup flag set, client_proc(%s) PID(%d) mask[%x]\n", client->proc_name, client->pid, mask); @@ -400,7 +397,10 @@ wl_client_connection_data(int fd, uint32_t mask, void *data) } if (mask & WL_EVENT_WRITABLE) { + pthread_mutex_lock(&client->connection_mutex); len = wl_connection_flush(connection); + pthread_mutex_unlock(&client->connection_mutex); + if (len < 0) wl_log("client_proc(%s) PID(%d) flush failed: len(%d) errno(%d)\n", client->proc_name, client->pid, len, errno); @@ -416,7 +416,9 @@ wl_client_connection_data(int fd, uint32_t mask, void *data) len = 0; if (mask & WL_EVENT_READABLE) { + pthread_mutex_lock(&client->connection_mutex); len = wl_connection_read(connection); + pthread_mutex_unlock(&client->connection_mutex); if (len <= 0) wl_log("client_proc(%s) PID(%d) read failed: len(%d) errno(%d)\n", client->proc_name, client->pid, len, errno); @@ -428,14 +430,18 @@ wl_client_connection_data(int fd, uint32_t mask, void *data) } while (len >= 0 && (size_t) len >= sizeof p) { + pthread_mutex_lock(&client->connection_mutex); wl_connection_copy(connection, p, sizeof p); + pthread_mutex_unlock(&client->connection_mutex); opcode = p[1] & 0xffff; size = p[1] >> 16; if (len < size) break; + pthread_mutex_lock(&client->objects_mutex); resource = wl_map_lookup(&client->objects, p[0]); resource_flags = wl_map_lookup_flags(&client->objects, p[0]); + pthread_mutex_unlock(&client->objects_mutex); if (resource == NULL) { wl_resource_post_error(client->display_resource, WL_DISPLAY_ERROR_INVALID_OBJECT, @@ -468,23 +474,30 @@ wl_client_connection_data(int fd, uint32_t mask, void *data) break; } - + pthread_mutex_lock(&client->connection_mutex); + pthread_mutex_lock(&client->objects_mutex); closure = wl_connection_demarshal(client->connection, size, &client->objects, message); + pthread_mutex_unlock(&client->objects_mutex); + pthread_mutex_unlock(&client->connection_mutex); if (closure == NULL && errno == ENOMEM) { wl_resource_post_no_memory(resource); break; - } else if (closure == NULL || - wl_closure_lookup_objects(closure, &client->objects) < 0) { - wl_resource_post_error(client->display_resource, - WL_DISPLAY_ERROR_INVALID_METHOD, - "invalid arguments for %s@%u.%s", - object->interface->name, - object->id, - message->name); - wl_closure_destroy(closure); - break; + } else { + pthread_mutex_lock(&client->objects_mutex); + int lookup_ret = wl_closure_lookup_objects(closure, &client->objects); + pthread_mutex_unlock(&client->objects_mutex); + if (closure == NULL || lookup_ret < 0) { + wl_resource_post_error(client->display_resource, + WL_DISPLAY_ERROR_INVALID_METHOD, + "invalid arguments for %s@%u.%s", + object->interface->name, + object->id, + message->name); + wl_closure_destroy(closure); + break; + } } log_closure(resource, closure, false); @@ -503,7 +516,9 @@ wl_client_connection_data(int fd, uint32_t mask, void *data) if (client->error) break; + pthread_mutex_lock(&client->connection_mutex); len = wl_connection_pending_input(connection); + pthread_mutex_unlock(&client->connection_mutex); } if (client->error) { @@ -514,9 +529,6 @@ wl_client_connection_data(int fd, uint32_t mask, void *data) } end: - pthread_mutex_unlock(&client->objects_mutex); - pthread_mutex_unlock(&client->connection_mutex); - return 1; } @@ -856,10 +868,10 @@ wl_resource_destroy(struct wl_resource *resource) uint32_t id; uint32_t flags; - pthread_mutex_lock(&client->objects_mutex); - id = resource->object.id; + pthread_mutex_lock(&client->objects_mutex); flags = wl_map_lookup_flags(&client->objects, id); + pthread_mutex_unlock(&client->objects_mutex); destroy_resource(resource, NULL, flags); if (id < WL_SERVER_ID_START) { @@ -867,12 +879,14 @@ wl_resource_destroy(struct wl_resource *resource) wl_resource_queue_event(client->display_resource, WL_DISPLAY_DELETE_ID, id); } + pthread_mutex_lock(&client->objects_mutex); wl_map_insert_at(&client->objects, 0, id, NULL); + pthread_mutex_unlock(&client->objects_mutex); } else { + pthread_mutex_lock(&client->objects_mutex); wl_map_remove(&client->objects, id); + pthread_mutex_unlock(&client->objects_mutex); } - - pthread_mutex_unlock(&client->objects_mutex); } WL_EXPORT uint32_t -- 2.7.4