summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVictor Toso <me@victortoso.com>2017-02-02 14:51:08 +0100
committerVictor Toso <me@victortoso.com>2017-03-02 15:34:29 +0100
commit7a33ce920d2a2b5fed30256591df06aaca49dd08 (patch)
tree0ed98c378739032c119baf8626162437ccf6d721
parent24ea304da8327090176cdea01349902be91526d0 (diff)
spice-channel: move out non blocking logic of _read_wire()
This patch introduces spice_channel_read_wire_nonblocking() helper without changing any logic. Related: https://bugs.freedesktop.org/show_bug.cgi?id=96598 Signed-off-by: Victor Toso <victortoso@redhat.com> Acked-by: Christophe Fergeau <cfergeau@redhat.com>
-rw-r--r--src/spice-channel.c45
1 files changed, 34 insertions, 11 deletions
diff --git a/src/spice-channel.c b/src/spice-channel.c
index af67931..4210c31 100644
--- a/src/spice-channel.c
+++ b/src/spice-channel.c
@@ -971,29 +971,32 @@ gint spice_channel_unix_read_fd(SpiceChannel *channel)
#endif
/*
- * Read at least 1 more byte of data straight off the wire
- * into the requested buffer.
+ * Helper function to deal with the nonblocking part of _read_wire() function.
+ * It returns the result of the read and will set the proper bits in @cond in
+ * case the read function would block.
+ *
+ * Returns -1 in case of any problems.
*/
/* coroutine context */
-static int spice_channel_read_wire(SpiceChannel *channel, void *data, size_t len)
+static int spice_channel_read_wire_nonblocking(SpiceChannel *channel,
+ void *data,
+ size_t len,
+ GIOCondition *cond)
{
SpiceChannelPrivate *c = channel->priv;
gssize ret;
- GIOCondition cond;
-
-reread:
- if (c->has_error) return 0; /* has_error is set by disconnect(), return no error */
+ g_assert(cond != NULL);
+ *cond = 0;
- cond = 0;
if (c->tls) {
ret = SSL_read(c->ssl, data, len);
if (ret < 0) {
ret = SSL_get_error(c->ssl, ret);
if (ret == SSL_ERROR_WANT_READ)
- cond |= G_IO_IN;
+ *cond |= G_IO_IN;
if (ret == SSL_ERROR_WANT_WRITE)
- cond |= G_IO_OUT;
+ *cond |= G_IO_OUT;
ret = -1;
}
} else {
@@ -1002,7 +1005,7 @@ reread:
data, len, NULL, &error);
if (ret < 0) {
if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
- cond = G_IO_IN;
+ *cond = G_IO_IN;
} else {
CHANNEL_DEBUG(channel, "Read error %s", error->message);
}
@@ -1011,6 +1014,26 @@ reread:
}
}
+ return ret;
+}
+
+/*
+ * Read at least 1 more byte of data straight off the wire
+ * into the requested buffer.
+ */
+/* coroutine context */
+static int spice_channel_read_wire(SpiceChannel *channel, void *data, size_t len)
+{
+ SpiceChannelPrivate *c = channel->priv;
+ GIOCondition cond;
+ gssize ret;
+
+reread:
+
+ if (c->has_error) return 0; /* has_error is set by disconnect(), return no error */
+
+ ret = spice_channel_read_wire_nonblocking(channel, data, len, &cond);
+
if (ret == -1) {
if (cond != 0) {
// TODO: should use g_pollable_input/output_stream_create_source() ?