summaryrefslogtreecommitdiffstats
path: root/patches/0001-Add-thread-affinity-to-wayland-clients.patch
diff options
context:
space:
mode:
authorJørgen Lind <jorgen.lind@nokia.com>2012-03-12 14:58:51 +0100
committerSamuel Rødal <samuel.rodal@nokia.com>2012-03-12 15:01:31 +0100
commit6f95a1515d92f04c4f185a686688c39f9a9a489e (patch)
treee714a2b6d844db40fc24a7b8d7fefb3d3037ab59 /patches/0001-Add-thread-affinity-to-wayland-clients.patch
parente285b5d9a326ce08e8035b120e97473456ec5919 (diff)
Updated to use the Thread affinity patch that we tried to upstream
Change-Id: I2de76d112d534588c3758213d8f5d6dd6e8c82df Reviewed-by: Samuel Rødal <samuel.rodal@nokia.com>
Diffstat (limited to 'patches/0001-Add-thread-affinity-to-wayland-clients.patch')
-rw-r--r--patches/0001-Add-thread-affinity-to-wayland-clients.patch253
1 files changed, 253 insertions, 0 deletions
diff --git a/patches/0001-Add-thread-affinity-to-wayland-clients.patch b/patches/0001-Add-thread-affinity-to-wayland-clients.patch
new file mode 100644
index 000000000..3838a22b7
--- /dev/null
+++ b/patches/0001-Add-thread-affinity-to-wayland-clients.patch
@@ -0,0 +1,253 @@
+From 24b8dccb2f48bc8595d40288106d51d3f4605544 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?J=C3=B8rgen=20Lind?= <jorgen.lind@nokia.com>
+Date: Mon, 5 Mar 2012 12:44:37 +0100
+Subject: [PATCH 1/2] Add thread affinity to wayland clients
+
+This makes it possible to marshal requests from more than 1 thread in
+wayland clients. However, its not possible to run wl_display_iterate
+from other threads than the thread that made the wl_display.
+---
+ src/Makefile.am | 2 +
+ src/wayland-client.c | 109 +++++++++++++++++++++++++++++++++++++++++++++++--
+ src/wayland-client.h | 6 +++
+ 3 files changed, 112 insertions(+), 5 deletions(-)
+
+diff --git a/src/Makefile.am b/src/Makefile.am
+index f356b54..9aab9de 100644
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -24,6 +24,8 @@ libwayland_server_la_SOURCES = \
+ event-loop.c
+
+ libwayland_client_la_LIBADD = $(FFI_LIBS) libwayland-util.la -lrt
++libwayland_client_la_LDFLAGS = -pthread
++libwayland_client_la_CFLAGS = -pthread
+ libwayland_client_la_SOURCES = \
+ wayland-protocol.c \
+ wayland-client.c
+diff --git a/src/wayland-client.c b/src/wayland-client.c
+index 498a429..9eb4b25 100644
+--- a/src/wayland-client.c
++++ b/src/wayland-client.c
+@@ -34,6 +34,7 @@
+ #include <assert.h>
+ #include <fcntl.h>
+ #include <sys/poll.h>
++#include <sys/eventfd.h>
+
+ #include "wayland-util.h"
+ #include "wayland-client.h"
+@@ -62,6 +63,9 @@ struct wl_display {
+ struct wl_proxy proxy;
+ struct wl_connection *connection;
+ int fd;
++ int write_notification_event_fd;
++ pthread_t thread_id;
++ pthread_mutex_t marshalling_mutex;
+ uint32_t mask;
+ struct wl_map objects;
+ struct wl_list global_listener_list;
+@@ -191,7 +195,11 @@ wl_proxy_marshal(struct wl_proxy *proxy, uint32_t opcode, ...)
+ {
+ struct wl_closure *closure;
+ va_list ap;
++ int write_notification_event_fd;
++ uint64_t write_notification_value;
++ ssize_t success;
+
++ pthread_mutex_lock(&proxy->display->marshalling_mutex);
+ va_start(ap, opcode);
+ closure = wl_connection_vmarshal(proxy->display->connection,
+ &proxy->object, opcode, ap,
+@@ -212,6 +220,18 @@ wl_proxy_marshal(struct wl_proxy *proxy, uint32_t opcode, ...)
+ wl_closure_print(closure, &proxy->object, true);
+
+ wl_closure_destroy(closure);
++
++ write_notification_event_fd = proxy->display->write_notification_event_fd;
++ write_notification_value = 1;
++ success = write(write_notification_event_fd,&write_notification_value,8);
++ if (success < 0) {
++ fprintf(stderr,
++ "Error writing to eventfd %d: %s\n",
++ write_notification_event_fd,
++ strerror(errno));
++ }
++
++ pthread_mutex_unlock(&proxy->display->marshalling_mutex);
+ }
+
+ /* Can't do this, there may be more than one instance of an
+@@ -347,6 +367,7 @@ wl_display_connect(const char *name)
+ const char *debug;
+ char *connection, *end;
+ int flags;
++ int success;
+
+ debug = getenv("WAYLAND_DEBUG");
+ if (debug)
+@@ -396,6 +417,21 @@ wl_display_connect(const char *name)
+ return NULL;
+ }
+
++ display->write_notification_event_fd = eventfd(0, EFD_CLOEXEC);
++ if (display->write_notification_event_fd < 0) {
++ fprintf(stderr, "Failed to create eventfd\n");
++ }
++
++ display->thread_id = pthread_self();
++ pthread_mutexattr_t mutex_attr;
++ success = pthread_mutexattr_init(&mutex_attr);
++ success += pthread_mutexattr_settype(&mutex_attr,PTHREAD_MUTEX_RECURSIVE);
++ success += pthread_mutex_init(&display->marshalling_mutex, &mutex_attr);
++ success += pthread_mutexattr_destroy(&mutex_attr);
++
++ if (success)
++ fprintf(stderr, "Threading setup was unsuccessfull\n");
++
+ return display;
+ }
+
+@@ -432,6 +468,18 @@ wl_display_get_fd(struct wl_display *display,
+ return display->fd;
+ }
+
++WL_EXPORT int
++wl_display_get_write_notification_fd(struct wl_display *display)
++{
++ return display->write_notification_event_fd;
++}
++
++WL_EXPORT pthread_t
++wl_display_thread(struct wl_display *display)
++{
++ return display->thread_id;
++}
++
+ static void
+ sync_callback(void *data, struct wl_callback *callback, uint32_t time)
+ {
+@@ -445,18 +493,46 @@ static const struct wl_callback_listener sync_listener = {
+ sync_callback
+ };
+
++static void
++threaded_sync_callback(void *data, struct wl_callback *callback, uint32_t time)
++{
++ fprintf(stderr, "threaded_sync_callback\n");
++ pthread_cond_t *wait_condition = data;
++
++ pthread_cond_broadcast(wait_condition);
++ wl_callback_destroy(callback);
++}
++
++static const struct wl_callback_listener threaded_sync_listener = {
++ threaded_sync_callback
++};
++
+ WL_EXPORT void
+ wl_display_roundtrip(struct wl_display *display)
+ {
+ struct wl_callback *callback;
+ int done;
++ pthread_cond_t wait_cond;
++ pthread_mutex_t wait_mutex;
+
+- done = 0;
+ callback = wl_display_sync(display);
+- wl_callback_add_listener(callback, &sync_listener, &done);
+- wl_display_flush(display);
+- while (!done)
+- wl_display_iterate(display, WL_DISPLAY_READABLE);
++
++ if (wl_display_thread(display) == pthread_self()) {
++ done = 0;
++ wl_callback_add_listener(callback, &sync_listener, &done);
++ wl_display_flush(display);
++ while (!done)
++ wl_display_iterate(display, WL_DISPLAY_READABLE);
++ } else {
++ pthread_mutex_init(&wait_mutex,NULL);
++ pthread_cond_init(&wait_cond, NULL);
++ pthread_mutex_lock(&wait_mutex);
++
++ wl_callback_add_listener(callback, &threaded_sync_listener, &wait_cond);
++ pthread_cond_wait(&wait_cond,&wait_mutex);
++ pthread_cond_destroy(&wait_cond);
++ pthread_mutex_destroy(&wait_mutex);
++ }
+ }
+
+ static void
+@@ -500,7 +576,11 @@ WL_EXPORT void
+ wl_display_iterate(struct wl_display *display, uint32_t mask)
+ {
+ uint32_t p[2], object, opcode, size;
++ uint64_t write_fd;
+ int len;
++ ssize_t success;
++
++ pthread_mutex_lock(&display->marshalling_mutex);
+
+ mask &= display->mask;
+ if (mask == 0) {
+@@ -509,6 +589,23 @@ wl_display_iterate(struct wl_display *display, uint32_t mask)
+ return;
+ }
+
++ if (mask & WL_DISPLAY_WRITABLE) {
++ if (pthread_self() != display->thread_id) {
++ fprintf(stderr,
++ "wl_display_iterate called with WL_DISPLAY_WRITABLE"
++ "from another thread than the thead that created "
++ "wl_display. This will result in events being dispatched"
++ "in other threads\n");
++ }
++ success = read(display->write_notification_event_fd, &write_fd, 8);
++ if (success < 0) {
++ fprintf(stderr,
++ "wl_display_iterate eventfd %d error at read: %s\n",
++ display->write_notification_event_fd,
++ strerror(errno));
++ }
++ }
++
+ len = wl_connection_data(display->connection, mask);
+
+ while (len > 0) {
+@@ -526,6 +623,8 @@ wl_display_iterate(struct wl_display *display, uint32_t mask)
+ len -= size;
+ }
+
++ pthread_mutex_unlock(&display->marshalling_mutex);
++
+ if (len < 0) {
+ fprintf(stderr, "read error: %m\n");
+ exit(EXIT_FAILURE);
+diff --git a/src/wayland-client.h b/src/wayland-client.h
+index b04a7ef..a680cab 100644
+--- a/src/wayland-client.h
++++ b/src/wayland-client.h
+@@ -25,6 +25,9 @@
+
+ #include "wayland-util.h"
+
++#include <pthread.h>
++#define WAYLAND_CLIENT_THREAD_AFFINITY
++
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+@@ -94,6 +97,9 @@ uint32_t
+ wl_display_get_global(struct wl_display *display,
+ const char *interface, uint32_t version);
+
++int wl_display_get_write_notification_fd(struct wl_display *display);
++pthread_t wl_display_thread(struct wl_display *display);
++
+ #ifdef __cplusplus
+ }
+ #endif
+--
+1.7.5.4
+