[Spice-devel] [spice-gtk v2 3/4] spice-channel: move out non blocking logic of _flush_wire()

Victor Toso victortoso at redhat.com
Fri Feb 3 15:13:39 UTC 2017


From: Victor Toso <me at victortoso.com>

This patch introduces spice_channel_flush_wire_nonblocking() helper
without changing any logic.

Related: https://bugs.freedesktop.org/show_bug.cgi?id=96598
Signed-off-by: Victor Toso <victortoso at redhat.com>
---
 src/spice-channel.c | 73 +++++++++++++++++++++++++++++++++++------------------
 1 file changed, 48 insertions(+), 25 deletions(-)

diff --git a/src/spice-channel.c b/src/spice-channel.c
index d1714df..9e43c6c 100644
--- a/src/spice-channel.c
+++ b/src/spice-channel.c
@@ -769,6 +769,53 @@ void spice_msg_out_send_internal(SpiceMsgOut *out)
 }
 
 /*
+ * Helper function to deal with the nonblocking part of _flush_wire() function.
+ * It returns the result of the write and will set the proper bits in @cond in
+ * case the write function would block.
+ *
+ * Returns -1 in case of any problems.
+ */
+/* coroutine context */
+static gint spice_channel_flush_wire_nonblocking(SpiceChannel *channel,
+                                                 const gchar *ptr,
+                                                 size_t len,
+                                                 GIOCondition *cond)
+{
+    SpiceChannelPrivate *c = channel->priv;
+    gssize ret;
+
+    g_assert(cond != NULL);
+    *cond = 0;
+
+    if (c->tls) {
+        ret = SSL_write(c->ssl, ptr, len);
+        if (ret < 0) {
+            ret = SSL_get_error(c->ssl, ret);
+            if (ret == SSL_ERROR_WANT_READ)
+                *cond |= G_IO_IN;
+            if (ret == SSL_ERROR_WANT_WRITE)
+                *cond |= G_IO_OUT;
+            ret = -1;
+        }
+    } else {
+        GError *error = NULL;
+        ret = g_pollable_output_stream_write_nonblocking(G_POLLABLE_OUTPUT_STREAM(c->out),
+                                                         ptr, len, NULL, &error);
+        if (ret < 0) {
+            if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
+                *cond = G_IO_OUT;
+            } else {
+                CHANNEL_DEBUG(channel, "Send error %s", error->message);
+            }
+            g_clear_error(&error);
+            ret = -1;
+        }
+    }
+
+    return ret;
+}
+
+/*
  * Write all 'data' of length 'datalen' bytes out to
  * the wire
  */
@@ -784,34 +831,10 @@ static void spice_channel_flush_wire(SpiceChannel *channel,
 
     while (offset < datalen) {
         gssize ret;
-        GError *error = NULL;
 
         if (c->has_error) return;
 
-        cond = 0;
-        if (c->tls) {
-            ret = SSL_write(c->ssl, ptr+offset, datalen-offset);
-            if (ret < 0) {
-                ret = SSL_get_error(c->ssl, ret);
-                if (ret == SSL_ERROR_WANT_READ)
-                    cond |= G_IO_IN;
-                if (ret == SSL_ERROR_WANT_WRITE)
-                    cond |= G_IO_OUT;
-                ret = -1;
-            }
-        } else {
-            ret = g_pollable_output_stream_write_nonblocking(G_POLLABLE_OUTPUT_STREAM(c->out),
-                                                             ptr+offset, datalen-offset, NULL, &error);
-            if (ret < 0) {
-                if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
-                    cond = G_IO_OUT;
-                } else {
-                    CHANNEL_DEBUG(channel, "Send error %s", error->message);
-                }
-                g_clear_error(&error);
-                ret = -1;
-            }
-        }
+        ret = spice_channel_flush_wire_nonblocking(channel, ptr+offset, datalen-offset, &cond);
         if (ret == -1) {
             if (cond != 0) {
                 // TODO: should use g_pollable_input/output_stream_create_source() in 2.28 ?
-- 
2.9.3



More information about the Spice-devel mailing list