|
|
2580a2 |
From f5e24c5cf77b92ab2737eb230db7ae0b2fb102cc Mon Sep 17 00:00:00 2001
|
|
|
2580a2 |
From: Frediano Ziglio <freddy77@gmail.com>
|
|
|
2580a2 |
Date: Sat, 17 Sep 2022 09:28:08 +0100
|
|
|
2580a2 |
Subject: [PATCH 5/8] Recreate watch if needed
|
|
|
2580a2 |
|
|
|
2580a2 |
Do not always watch for output buffer.
|
|
|
2580a2 |
Watching for output buffer if we don't have nothing to write
|
|
|
2580a2 |
(which is the usual case) is consuming a lot of CPU.
|
|
|
2580a2 |
|
|
|
2580a2 |
This fixes https://gitlab.freedesktop.org/spice/usbredir/-/issues/24.
|
|
|
2580a2 |
|
|
|
2580a2 |
Signed-off-by: Frediano Ziglio <freddy77@gmail.com>
|
|
|
2580a2 |
---
|
|
|
2580a2 |
tools/usbredirect.c | 28 ++++++++++++++++++++++++++--
|
|
|
2580a2 |
1 file changed, 26 insertions(+), 2 deletions(-)
|
|
|
2580a2 |
|
|
|
2580a2 |
diff --git a/tools/usbredirect.c b/tools/usbredirect.c
|
|
|
2580a2 |
index 6a8b68b..b6a30ad 100644
|
|
|
2580a2 |
--- a/tools/usbredirect.c
|
|
|
2580a2 |
+++ b/tools/usbredirect.c
|
|
|
2580a2 |
@@ -29,6 +29,7 @@ typedef struct redirect {
|
|
|
2580a2 |
} device;
|
|
|
2580a2 |
bool is_client;
|
|
|
2580a2 |
bool keepalive;
|
|
|
2580a2 |
+ bool watch_inout;
|
|
|
2580a2 |
char *addr;
|
|
|
2580a2 |
int port;
|
|
|
2580a2 |
int verbosity;
|
|
|
2580a2 |
@@ -42,6 +43,8 @@ typedef struct redirect {
|
|
|
2580a2 |
GMainLoop *main_loop;
|
|
|
2580a2 |
} redirect;
|
|
|
2580a2 |
|
|
|
2580a2 |
+static void create_watch(redirect *self);
|
|
|
2580a2 |
+
|
|
|
2580a2 |
static bool
|
|
|
2580a2 |
parse_opt_device(const char *device, int *vendor, int *product)
|
|
|
2580a2 |
{
|
|
|
2580a2 |
@@ -162,6 +165,7 @@ parse_opts(int *argc, char ***argv)
|
|
|
2580a2 |
}
|
|
|
2580a2 |
|
|
|
2580a2 |
self = g_new0(redirect, 1);
|
|
|
2580a2 |
+ self->watch_inout = true;
|
|
|
2580a2 |
if (!parse_opt_device(device, &self->device.vendor, &self->device.product)) {
|
|
|
2580a2 |
g_printerr("Failed to parse device: '%s' - expected: vendor:product or busnum-devnum\n", device);
|
|
|
2580a2 |
g_clear_pointer(&self, g_free);
|
|
|
2580a2 |
@@ -276,6 +280,20 @@ usbredir_log_cb(void *priv, int level, const char *msg)
|
|
|
2580a2 |
g_log_structured(G_LOG_DOMAIN, glog_level, "MESSAGE", msg);
|
|
|
2580a2 |
}
|
|
|
2580a2 |
|
|
|
2580a2 |
+static void
|
|
|
2580a2 |
+update_watch(redirect *self)
|
|
|
2580a2 |
+{
|
|
|
2580a2 |
+ const bool watch_inout = usbredirhost_has_data_to_write(self->usbredirhost) != 0;
|
|
|
2580a2 |
+ if (watch_inout == self->watch_inout) {
|
|
|
2580a2 |
+ return;
|
|
|
2580a2 |
+ }
|
|
|
2580a2 |
+ g_source_remove(self->watch_server_id);
|
|
|
2580a2 |
+ self->watch_server_id = 0;
|
|
|
2580a2 |
+ self->watch_inout = watch_inout;
|
|
|
2580a2 |
+
|
|
|
2580a2 |
+ create_watch(self);
|
|
|
2580a2 |
+}
|
|
|
2580a2 |
+
|
|
|
2580a2 |
static int
|
|
|
2580a2 |
usbredir_read_cb(void *priv, uint8_t *data, int count)
|
|
|
2580a2 |
{
|
|
|
2580a2 |
@@ -321,6 +339,7 @@ usbredir_write_cb(void *priv, uint8_t *data, int count)
|
|
|
2580a2 |
if (g_error_matches(err, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
|
|
|
2580a2 |
/* Try again later */
|
|
|
2580a2 |
nbytes = 0;
|
|
|
2580a2 |
+ update_watch(self);
|
|
|
2580a2 |
} else {
|
|
|
2580a2 |
if (err != NULL) {
|
|
|
2580a2 |
g_warning("Failure at %s: %s", __func__, err->message);
|
|
|
2580a2 |
@@ -400,13 +419,18 @@ connection_handle_io_cb(GIOChannel *source, GIOCondition condition, gpointer use
|
|
|
2580a2 |
goto end;
|
|
|
2580a2 |
}
|
|
|
2580a2 |
}
|
|
|
2580a2 |
- if (condition & G_IO_OUT) {
|
|
|
2580a2 |
+ // try to write data in any case, to avoid having another iteration and
|
|
|
2580a2 |
+ // creation of another watch if there is space in output buffer
|
|
|
2580a2 |
+ if (usbredirhost_has_data_to_write(self->usbredirhost) != 0) {
|
|
|
2580a2 |
int ret = usbredirhost_write_guest_data(self->usbredirhost);
|
|
|
2580a2 |
if (ret < 0) {
|
|
|
2580a2 |
g_critical("%s: Failed to write to guest", __func__);
|
|
|
2580a2 |
goto end;
|
|
|
2580a2 |
}
|
|
|
2580a2 |
}
|
|
|
2580a2 |
+
|
|
|
2580a2 |
+ // update the watch if needed
|
|
|
2580a2 |
+ update_watch(self);
|
|
|
2580a2 |
return G_SOURCE_CONTINUE;
|
|
|
2580a2 |
|
|
|
2580a2 |
end:
|
|
|
2580a2 |
@@ -427,7 +451,7 @@ create_watch(redirect *self)
|
|
|
2580a2 |
#endif
|
|
|
2580a2 |
|
|
|
2580a2 |
self->watch_server_id = g_io_add_watch(io_channel,
|
|
|
2580a2 |
- G_IO_IN | G_IO_OUT | G_IO_HUP | G_IO_ERR,
|
|
|
2580a2 |
+ G_IO_IN | G_IO_HUP | G_IO_ERR | (self->watch_inout ? G_IO_OUT : 0),
|
|
|
2580a2 |
connection_handle_io_cb,
|
|
|
2580a2 |
self);
|
|
|
2580a2 |
}
|
|
|
2580a2 |
--
|
|
|
2580a2 |
2.39.0
|
|
|
2580a2 |
|