diff options
author | Kristian Høgsberg <krh@bitplanet.net> | 2012-10-04 17:42:49 -0400 |
---|---|---|
committer | Kristian Høgsberg <krh@bitplanet.net> | 2012-10-04 17:42:49 -0400 |
commit | 825c32f4fdcc9fa079b9c7dda608cde2b03da797 (patch) | |
tree | 702de0bde5220f09f5e3a2c2ee6bd4071a0d0d06 | |
parent | f66f0dd5816804c112cc3c9554d5fb4509e10a34 (diff) |
client: Make wl_display thread safefd-changes
Not all entry points are thread safe: global listeners and global lookup
is still only main thread.
-rw-r--r-- | src/wayland-client.c | 33 |
1 files changed, 31 insertions, 2 deletions
diff --git a/src/wayland-client.c b/src/wayland-client.c index c6ea045..bba6cdf 100644 --- a/src/wayland-client.c +++ b/src/wayland-client.c @@ -35,6 +35,7 @@ #include <assert.h> #include <fcntl.h> #include <sys/poll.h> +#include <pthread.h> #include "wayland-util.h" #include "wayland-os.h" @@ -68,6 +69,7 @@ struct wl_display { struct wl_map objects; struct wl_list global_listener_list; struct wl_list global_list; + pthread_mutex_t mutex; wl_display_global_func_t global_handler; void *global_handler_data; @@ -117,9 +119,12 @@ wl_proxy_create(struct wl_proxy *factory, const struct wl_interface *interface) proxy->object.interface = interface; proxy->object.implementation = NULL; + proxy->display = display; + + pthread_mutex_lock(&display->mutex); proxy->object.id = wl_map_insert_new(&display->objects, WL_MAP_CLIENT_SIDE, proxy); - proxy->display = display; + pthread_mutex_unlock(&display->mutex); return proxy; } @@ -139,7 +144,10 @@ wl_proxy_create_for_id(struct wl_proxy *factory, proxy->object.implementation = NULL; proxy->object.id = id; proxy->display = display; + + pthread_mutex_lock(&display->mutex); wl_map_insert_at(&display->objects, id, proxy); + pthread_mutex_unlock(&display->mutex); return proxy; } @@ -147,12 +155,17 @@ wl_proxy_create_for_id(struct wl_proxy *factory, WL_EXPORT void wl_proxy_destroy(struct wl_proxy *proxy) { + pthread_mutex_lock(&proxy->display->mutex); + if (proxy->object.id < WL_SERVER_ID_START) wl_map_insert_at(&proxy->display->objects, proxy->object.id, WL_ZOMBIE_OBJECT); else wl_map_insert_at(&proxy->display->objects, proxy->object.id, NULL); + + pthread_mutex_unlock(&proxy->display->mutex); + free(proxy); } @@ -177,6 +190,8 @@ wl_proxy_marshal(struct wl_proxy *proxy, uint32_t opcode, ...) struct wl_closure *closure; va_list ap; + pthread_mutex_lock(&proxy->display->mutex); + va_start(ap, opcode); closure = wl_closure_vmarshal(&proxy->object, opcode, ap, &proxy->object.interface->methods[opcode]); @@ -196,6 +211,8 @@ wl_proxy_marshal(struct wl_proxy *proxy, uint32_t opcode, ...) } wl_closure_destroy(closure); + + pthread_mutex_unlock(&proxy->display->mutex); } /* Can't do this, there may be more than one instance of an @@ -269,11 +286,15 @@ display_handle_delete_id(void *data, struct wl_display *display, uint32_t id) { struct wl_proxy *proxy; + pthread_mutex_lock(&display->mutex); + proxy = wl_map_lookup(&display->objects, id); if (proxy != WL_ZOMBIE_OBJECT) fprintf(stderr, "server sent delete_id for live object\n"); else wl_map_remove(&display->objects, id); + + pthread_mutex_unlock(&display->mutex); } static const struct wl_display_listener display_listener = { @@ -550,8 +571,10 @@ wl_display_dispatch(struct wl_display *display) struct wl_proxy *proxy; int len, size, opcode; + pthread_mutex_lock(&display->mutex); + /* FIXME: Handle flush errors, EAGAIN... */ - wl_display_flush(display); + wl_connection_flush(display->connection); /* FIXME: Shouldn't always read here... */ len = wl_connection_read(display->connection); @@ -566,6 +589,8 @@ wl_display_dispatch(struct wl_display *display) len -= size; } + pthread_mutex_unlock(&display->mutex); + while (!wl_list_empty(&list)) { closure = container_of(list.next, struct wl_closure, link); opcode = closure->buffer[1] & 0xffff; @@ -585,10 +610,14 @@ wl_display_flush(struct wl_display *display) { int ret; + pthread_mutex_lock(&display->mutex); + do { ret = wl_connection_flush(display->connection); } while (ret > 0); + pthread_mutex_unlock(&display->mutex); + return ret; } |