wayland-server: Fix hangup issue 38/295138/3
authorJihoon Kim <jihoon48.kim@samsung.com>
Fri, 19 May 2023 08:29:15 +0000 (17:29 +0900)
committerSeunghun Lee <shiin.lee@samsung.com>
Tue, 4 Jul 2023 01:52:26 +0000 (01:52 +0000)
Change-Id: Ib175e0e239b63e6f6ec5a23d3960fe92deef0c14
Signed-off-by: Jihoon Kim <jihoon48.kim@samsung.com>
src/wayland-server.c

index b082d3e..4b32960 100644 (file)
@@ -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