summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@bitplanet.net>2012-10-04 17:42:49 -0400
committerKristian Høgsberg <krh@bitplanet.net>2012-10-04 17:42:49 -0400
commit825c32f4fdcc9fa079b9c7dda608cde2b03da797 (patch)
tree702de0bde5220f09f5e3a2c2ee6bd4071a0d0d06
parentf66f0dd5816804c112cc3c9554d5fb4509e10a34 (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.c33
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;
}