[Spice-devel] [spice-gtk 09/13] channel: talk to giostream instead of gsocket

Marc-André Lureau mlureau at redhat.com
Tue Feb 11 09:40:44 PST 2014



----- Original Message -----
> On Mon, Feb 03, 2014 at 07:02:40PM +0100, Marc-André Lureau wrote:
> > From: Marc-André Lureau <marcandre.lureau at redhat.com>
> > 
> > When using glib >= 2.28, use stream API rather than gsocket directly.
> > 
> > This allows for more flexible streams usage, including encoded streams
> > from proxy connections.
> > ---
> >  gtk/spice-channel-priv.h |  2 ++
> >  gtk/spice-channel.c      | 46
> >  ++++++++++++++++++++++++++++++++++------------
> >  spice-common             |  2 +-
> >  3 files changed, 37 insertions(+), 13 deletions(-)
> > 
> > diff --git a/gtk/spice-channel-priv.h b/gtk/spice-channel-priv.h
> > index 0816061..fd08b2a 100644
> > --- a/gtk/spice-channel-priv.h
> > +++ b/gtk/spice-channel-priv.h
> > @@ -82,6 +82,8 @@ struct _SpiceChannelPrivate {
> >      SpiceOpenSSLVerify          *sslverify;
> >      GSocket                     *sock;
> >      GSocketConnection           *conn;
> > +    GInputStream                *in;
> > +    GOutputStream               *out;
> >  
> >  #if HAVE_SASL
> >      sasl_conn_t                 *sasl_conn;
> > diff --git a/gtk/spice-channel.c b/gtk/spice-channel.c
> > index 9e97f28..7459a49 100644
> > --- a/gtk/spice-channel.c
> > +++ b/gtk/spice-channel.c
> > @@ -763,7 +763,8 @@ static void spice_channel_flush_wire(SpiceChannel
> > *channel,
> >      GIOCondition cond;
> >  
> >      while (offset < datalen) {
> > -        int ret;
> > +        gssize ret;
> > +        GError *error = NULL;
> >  
> >          if (c->has_error) return;
> >  
> > @@ -779,9 +780,12 @@ static void spice_channel_flush_wire(SpiceChannel
> > *channel,
> >                  ret = -1;
> >              }
> >          } else {
> > -            GError *error = NULL;
> > -            ret = g_socket_send(c->sock, ptr+offset, datalen-offset,
> > -                                NULL, &error);
> > +#if GLIB_CHECK_VERSION(2, 28, 0)
> > +            ret =
> > g_pollable_output_stream_write_nonblocking(G_POLLABLE_OUTPUT_STREAM(c->out),
> > +                                                             ptr+offset,
> > datalen-offset, NULL, &error);
> > +#else
> > +            ret = g_socket_send(c->sock, ptr+offset, datalen-offset, NULL,
> > &error);
> > +#endif
> >              if (ret < 0) {
> >                  if (g_error_matches(error, G_IO_ERROR,
> >                  G_IO_ERROR_WOULD_BLOCK)) {
> >                      cond = G_IO_OUT;
> > @@ -794,6 +798,7 @@ static void spice_channel_flush_wire(SpiceChannel
> > *channel,
> >          }
> >          if (ret == -1) {
> >              if (cond != 0) {
> > +                // TODO: should use
> > g_pollable_input/output_stream_create_source() in 2.28 ?
> >                  g_coroutine_socket_wait(&c->coroutine, c->sock, cond);
> >                  continue;
> >              } else {
> > @@ -888,7 +893,7 @@ static void spice_channel_write_msg(SpiceChannel
> > *channel, SpiceMsgOut *out)
> >  static int spice_channel_read_wire(SpiceChannel *channel, void *data,
> >  size_t len)
> >  {
> >      SpiceChannelPrivate *c = channel->priv;
> > -    int ret;
> > +    gssize ret;
> >      GIOCondition cond;
> >  
> >  reread:
> > @@ -908,7 +913,13 @@ reread:
> >          }
> >      } else {
> >          GError *error = NULL;
> > -        ret = g_socket_receive(c->sock, data, len, NULL, &error);
> > +#if GLIB_CHECK_VERSION(2, 28, 0)
> > +        ret =
> > g_pollable_input_stream_read_nonblocking(G_POLLABLE_INPUT_STREAM(c->in),
> > +                                                       data, len, NULL,
> > &error);
> > +#else
> > +        ret = g_socket_receive(c->sock,
> > +                               data, len, NULL, &error);
> > +#endif
> >          if (ret < 0) {
> >              if (g_error_matches(error, G_IO_ERROR,
> >              G_IO_ERROR_WOULD_BLOCK)) {
> >                  cond = G_IO_IN;
> > @@ -922,6 +933,7 @@ reread:
> >  
> >      if (ret == -1) {
> >          if (cond != 0) {
> > +            // TODO: should use
> > g_pollable_input/output_stream_create_source() ?
> >              g_coroutine_socket_wait(&c->coroutine, c->sock, cond);
> >              goto reread;
> >          } else {
> > @@ -2061,7 +2073,7 @@ static void spice_channel_iterate_read(SpiceChannel
> > *channel)
> >      /* treat all incoming data (block on message completion) */
> >      while (!c->has_error &&
> >             c->state != SPICE_CHANNEL_STATE_MIGRATING &&
> > -           g_socket_condition_check(c->sock, G_IO_IN) & G_IO_IN) {
> > +
> > g_pollable_input_stream_is_readable(G_POLLABLE_INPUT_STREAM(c->in)))
> > {
> 
> Doesn't this need #if GLIB_CHECK_VERSION(2, 28, 0) as well?
> 

yep

> >  
> >          do
> >              spice_channel_recv_msg(channel,
> > @@ -2236,9 +2248,11 @@ static void *spice_channel_coroutine(void *data)
> >  
> >          g_socket_set_blocking(c->sock, FALSE);
> >          g_socket_set_keepalive(c->sock, TRUE);
> > +        c->conn = g_socket_connection_factory_create_connection(c->sock);
> >          goto connected;
> >      }
> >  
> > +
> 
> Dunno if this blank space addition is intentional.

It does look slightly better with an empty line before the goto.

> >  reconnect:
> >      c->conn = spice_session_channel_open_host(c->session, channel,
> >      &c->tls);
> >      if (c->conn == NULL) {
> > @@ -2299,7 +2313,11 @@ reconnect:
> >          }
> >  
> >  
> > +#if GLIB_CHECK_VERSION(2, 28, 0)
> > +        BIO *bio = bio_new_giostream(G_IO_STREAM(c->conn));
> > +#else
> >          BIO *bio = bio_new_gsocket(c->sock);
> > +#endif
> >          SSL_set_bio(c->ssl, bio, bio);
> >  
> >          {
> > @@ -2330,6 +2348,9 @@ ssl_reconnect:
> >      }
> >  
> >  connected:
> > +    c->in = g_io_stream_get_input_stream(G_IO_STREAM(c->conn));
> > +    c->out = g_io_stream_get_output_stream(G_IO_STREAM(c->conn));
> > +
> >      rc = setsockopt(g_socket_get_fd(c->sock), IPPROTO_TCP, TCP_NODELAY,
> >                      (const char*)&delay_val, sizeof(delay_val));
> >      if ((rc != 0)
> > @@ -2503,10 +2524,9 @@ static void channel_reset(SpiceChannel *channel,
> > gboolean migrating)
> >          g_object_unref(c->conn);
> >          c->conn = NULL;
> >      }
> > -    if (c->sock) {
> > -        g_object_unref(c->sock);
> > -        c->sock = NULL;
> > -    }
> > +
> > +    g_clear_object(&c->sock);
> > +
> >      c->fd = -1;
> >  
> >      free(c->peer_msg);
> > @@ -2732,8 +2752,10 @@ void spice_channel_swap(SpiceChannel *channel,
> > SpiceChannel *swap, gboolean swap
> >  
> >      /* TODO: split channel in 2 objects: a controller and a swappable
> >         state object */
> > -    SWAP(conn);
> >      SWAP(sock);
> > +    SWAP(conn);
> > +    SWAP(in);
> > +    SWAP(out);
> >      SWAP(ctx);
> >      SWAP(ssl);
> >      SWAP(sslverify);
> > diff --git a/spice-common b/spice-common
> > index 57ce430..f7a6d3f 160000
> > --- a/spice-common
> > +++ b/spice-common
> > @@ -1 +1 @@
> > -Subproject commit 57ce430ccd66bd1ca2447c14503234cfb88e2365
> > +Subproject commit f7a6d3fa97b874f87497978babc69d0f65609f31
> 
> Is this needed?

nope

> Christophe
> 
> _______________________________________________
> Spice-devel mailing list
> Spice-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/spice-devel
> 


More information about the Spice-devel mailing list