From 3f7fcf83f6b1c9004aa20c936f10de8118d8ed8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Wed, 4 Sep 2013 22:12:28 -0700 Subject: [PATCH] xwm: Try a non-blocking write before setting up an fd watch for property data Typically we can write it immediately without blocking, so save the overhead of setting up an fd watch and writing the data in a callback. For the case where the immediate write doesn't write all data, we fallback and set up the fd watch as usual. This patch also consolidates setting up the async write a bit. --- src/xwayland/selection.c | 43 ++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/src/xwayland/selection.c b/src/xwayland/selection.c index 63c4c3fc..76063df0 100644 --- a/src/xwayland/selection.c +++ b/src/xwayland/selection.c @@ -30,7 +30,7 @@ #include "xwayland.h" static int -weston_wm_write_property(int fd, uint32_t mask, void *data) +writable_callback(int fd, uint32_t mask, void *data) { struct weston_wm *wm = data; unsigned char *property; @@ -43,7 +43,9 @@ weston_wm_write_property(int fd, uint32_t mask, void *data) len = write(fd, property + wm->property_start, remainder); if (len == -1) { free(wm->property_reply); - wl_event_source_remove(wm->property_source); + wm->property_reply = NULL; + if (wm->property_source) + wl_event_source_remove(wm->property_source); close(fd); weston_log("write error to target fd: %m\n"); return 1; @@ -56,7 +58,9 @@ weston_wm_write_property(int fd, uint32_t mask, void *data) wm->property_start += len; if (len == remainder) { free(wm->property_reply); - wl_event_source_remove(wm->property_source); + wm->property_reply = NULL; + if (wm->property_source) + wl_event_source_remove(wm->property_source); if (wm->incr) { xcb_delete_property(wm->conn, @@ -71,6 +75,21 @@ weston_wm_write_property(int fd, uint32_t mask, void *data) return 1; } +static void +weston_wm_write_property(struct weston_wm *wm, xcb_get_property_reply_t *reply) +{ + wm->property_start = 0; + wm->property_reply = reply; + writable_callback(wm->data_source_fd, WL_EVENT_WRITABLE, wm); + + if (wm->property_reply) + wm->property_source = + wl_event_loop_add_fd(wm->server->loop, + wm->data_source_fd, + WL_EVENT_WRITABLE, + writable_callback, wm); +} + static void weston_wm_get_incr_chunk(struct weston_wm *wm) { @@ -90,14 +109,7 @@ weston_wm_get_incr_chunk(struct weston_wm *wm) dump_property(wm, wm->atom.wl_selection, reply); if (xcb_get_property_value_length(reply) > 0) { - wm->property_start = 0; - wm->property_source = - wl_event_loop_add_fd(wm->server->loop, - wm->data_source_fd, - WL_EVENT_WRITABLE, - weston_wm_write_property, - wm); - wm->property_reply = reply; + weston_wm_write_property(wm, reply); } else { weston_log("transfer complete\n"); close(wm->data_source_fd); @@ -223,14 +235,7 @@ weston_wm_get_selection_data(struct weston_wm *wm) } else { dump_property(wm, wm->atom.wl_selection, reply); wm->incr = 0; - wm->property_start = 0; - wm->property_source = - wl_event_loop_add_fd(wm->server->loop, - wm->data_source_fd, - WL_EVENT_WRITABLE, - weston_wm_write_property, - wm); - wm->property_reply = reply; + weston_wm_write_property(wm, reply); } }