From: Victor Toso <me@xxxxxxxxxxxxxx> 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@xxxxxxxxxx> --- src/spice-channel.c | 45 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/src/spice-channel.c b/src/spice-channel.c index 6556db3..a17c402 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() ? -- 2.9.3 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel