[Spice-devel] [spice-server 03/10] Remove OutgoingHandlerInterface

Jonathon Jongsma jjongsma at redhat.com
Wed Feb 8 18:49:57 UTC 2017


On Tue, 2017-02-07 at 11:59 +0100, Christophe Fergeau wrote:
> RedChannel uses OutgoingHandlerInterface to provide constant pointers
> to
> RedChannelClient methods. This OutgoingHandlerInterface structure is
> then used in RedChannelClient to indirectly call these methods.
> 
> Since the content of OutgoingHandlerInterface is never modified, we
> can
> directly call the relevant methods and make them static.
> ---
>  server/red-channel-client-private.h |  1 -
>  server/red-channel-client.c         | 30 ++++++++++++++++-----------
> ---
>  server/red-channel-client.h         |  6 ------
>  server/red-channel.c                | 13 -------------
>  server/red-channel.h                | 20 +-------------------
>  5 files changed, 17 insertions(+), 53 deletions(-)
> 
> diff --git a/server/red-channel-client-private.h b/server/red-
> channel-client-private.h
> index d01cdbd..5d29f32 100644
> --- a/server/red-channel-client-private.h
> +++ b/server/red-channel-client-private.h
> @@ -41,7 +41,6 @@ typedef struct RedChannelClientConnectivityMonitor
> {
>  } RedChannelClientConnectivityMonitor;
>  
>  typedef struct OutgoingHandler {
> -    OutgoingHandlerInterface *cb;
>      void *opaque;
>      struct iovec vec_buf[IOV_MAX];
>      int vec_size;

So, after removing the 'cb' field here, we're basically left with some
buffers. In my mind, that makes OutgoingHandler a bit of a misnomer.
Perhaps we could rename it to something that describes its function a
bit better? 

> diff --git a/server/red-channel-client.c b/server/red-channel-
> client.c
> index 82c786f..a5c8e9f 100644
> --- a/server/red-channel-client.c
> +++ b/server/red-channel-client.c
> @@ -272,7 +272,6 @@ static void
> red_channel_client_constructed(GObject *object)
>      self->priv->incoming.cb = red_channel_get_incoming_handler(self-
> >priv->channel);
>  
>      self->priv->outgoing.opaque = self;
> -    self->priv->outgoing.cb = red_channel_get_outgoing_handler(self-
> >priv->channel);
>      self->priv->outgoing.pos = 0;
>      self->priv->outgoing.size = 0;
>  
> @@ -373,7 +372,7 @@ RedChannel*
> red_channel_client_get_channel(RedChannelClient *rcc)
>      return rcc->priv->channel;
>  }
>  
> -void red_channel_client_on_output(void *opaque, int n)
> +static void red_channel_client_on_output(void *opaque, int n)
>  {
>      RedChannelClient *rcc = opaque;
>      RedChannel *channel = red_channel_client_get_channel(rcc);
> @@ -381,6 +380,7 @@ void red_channel_client_on_output(void *opaque,
> int n)
>      if (rcc->priv->connectivity_monitor.timer) {
>          rcc->priv->connectivity_monitor.out_bytes += n;
>      }
> +    /* FIXME: use a signal rather than a hardcoded call to a
> RedChannel callback? */

That sounds nicer to me. That would remove the need to expose this from
the header (as I mentioned in the review for the last patch)

>      red_channel_on_output(channel, n);
>  }
>  
> @@ -393,15 +393,15 @@ void red_channel_client_on_input(void *opaque,
> int n)
>      }
>  }
>  
> -int red_channel_client_get_out_msg_size(void *opaque)
> +static int red_channel_client_get_out_msg_size(void *opaque)
>  {
>      RedChannelClient *rcc = RED_CHANNEL_CLIENT(opaque);
>  
>      return rcc->priv->send_data.size;
>  }
>  
> -void red_channel_client_prepare_out_msg(void *opaque, struct iovec
> *vec,
> -                                        int *vec_size, int pos)
> +static void red_channel_client_prepare_out_msg(void *opaque, struct
> iovec *vec,
> +                                               int *vec_size, int
> pos)
>  {
>      RedChannelClient *rcc = RED_CHANNEL_CLIENT(opaque);
>  
> @@ -409,7 +409,7 @@ void red_channel_client_prepare_out_msg(void
> *opaque, struct iovec *vec,
>                                              vec, IOV_MAX, pos);
>  }
>  
> -void red_channel_client_on_out_block(void *opaque)
> +static void red_channel_client_on_out_block(void *opaque)
>  {
>      SpiceCoreInterfaceInternal *core;
>      RedChannelClient *rcc = RED_CHANNEL_CLIENT(opaque);
> @@ -549,7 +549,7 @@ static void
> red_channel_client_restore_main_sender(RedChannelClient *rcc)
>      rcc->priv->send_data.header.data = rcc->priv-
> >send_data.main.header_data;
>  }
>  
> -void red_channel_client_on_out_msg_done(void *opaque)
> +static void red_channel_client_on_out_msg_done(void *opaque)
>  {
>      RedChannelClient *rcc = RED_CHANNEL_CLIENT(opaque);
>      int fd;
> @@ -1010,33 +1010,35 @@ static void
> red_peer_handle_outgoing(RedsStream *stream, OutgoingHandler *handle
>  
>      if (handler->size == 0) {
>          handler->vec = handler->vec_buf;
> -        handler->size = handler->cb->get_msg_size(handler->opaque);
> +        handler->size = red_channel_client_get_out_msg_size(handler-
> >opaque);
>          if (!handler->size) {  // nothing to be sent
>              return;
>          }
>      }
>  
>      for (;;) {
> -        handler->cb->prepare(handler->opaque, handler->vec,
> &handler->vec_size, handler->pos);
> +        red_channel_client_prepare_out_msg(handler->opaque, handler-
> >vec, &handler->vec_size, handler->pos);
>          n = reds_stream_writev(stream, handler->vec, handler-
> >vec_size);
>          if (n == -1) {
>              switch (errno) {
>              case EAGAIN:
> -                handler->cb->on_block(handler->opaque);
> +                red_channel_client_on_out_block(handler->opaque);
>                  return;
>              case EINTR:
>                  continue;
>              case EPIPE:
> -                handler->cb->on_error(handler->opaque);
> +                /* FIXME: handle disconnection in caller */
> +                red_channel_client_disconnect(handler->opaque);
>                  return;
>              default:
> +                /* FIXME: handle disconnection in caller */
>                  spice_printerr("%s", strerror(errno));
> -                handler->cb->on_error(handler->opaque);
> +                red_channel_client_disconnect(handler->opaque);
>                  return;
>              }
>          } else {
>              handler->pos += n;
> -            handler->cb->on_output(handler->opaque, n);
> +            red_channel_client_on_output(handler->opaque, n);
>              if (handler->pos == handler->size) { // finished writing
> data
>                  /* reset handler before calling on_msg_done, since
> it
>                   * can trigger another call to
> red_peer_handle_outgoing (when
> @@ -1044,7 +1046,7 @@ static void red_peer_handle_outgoing(RedsStream
> *stream, OutgoingHandler *handle
>                  handler->vec = handler->vec_buf;
>                  handler->pos = 0;
>                  handler->size = 0;
> -                handler->cb->on_msg_done(handler->opaque);
> +                red_channel_client_on_out_msg_done(handler->opaque);
>                  return;
>              }
>          }
> diff --git a/server/red-channel-client.h b/server/red-channel-
> client.h
> index fada609..6b6a61a 100644
> --- a/server/red-channel-client.h
> +++ b/server/red-channel-client.h
> @@ -175,13 +175,7 @@ void
> red_channel_client_disconnect_if_pending_send(RedChannelClient *rcc);
>  
>  RedChannel* red_channel_client_get_channel(RedChannelClient *rcc);
>  
> -void red_channel_client_on_output(void *opaque, int n);
>  void red_channel_client_on_input(void *opaque, int n);
> -int red_channel_client_get_out_msg_size(void *opaque);
> -void red_channel_client_prepare_out_msg(void *opaque, struct iovec
> *vec,
> -                                             int *vec_size, int
> pos);
> -void red_channel_client_on_out_block(void *opaque);
> -void red_channel_client_on_out_msg_done(void *opaque);
>  
>  void
> red_channel_client_semi_seamless_migration_complete(RedChannelClient
> *rcc);
>  void
> red_channel_client_init_outgoing_messages_window(RedChannelClient
> *rcc);
> diff --git a/server/red-channel.c b/server/red-channel.c
> index 92a22de..3abe9c7 100644
> --- a/server/red-channel.c
> +++ b/server/red-channel.c
> @@ -91,7 +91,6 @@ struct RedChannelPrivate
>      RedChannelCapabilities local_caps;
>      uint32_t migration_flags;
>  
> -    OutgoingHandlerInterface outgoing_cb;
>      IncomingHandlerInterface incoming_cb;
>  
>      ClientCbs client_cbs;
> @@ -333,13 +332,6 @@ red_channel_init(RedChannel *self)
>      self->priv->incoming_cb.on_error =
>          (on_incoming_error_proc)red_channel_client_default_peer_on_e
> rror;
>      self->priv->incoming_cb.on_input = red_channel_client_on_input;
> -    self->priv->outgoing_cb.get_msg_size =
> red_channel_client_get_out_msg_size;
> -    self->priv->outgoing_cb.prepare =
> red_channel_client_prepare_out_msg;
> -    self->priv->outgoing_cb.on_block =
> red_channel_client_on_out_block;
> -    self->priv->outgoing_cb.on_error =
> -        (on_outgoing_error_proc)red_channel_client_default_peer_on_e
> rror;
> -    self->priv->outgoing_cb.on_msg_done =
> red_channel_client_on_out_msg_done;
> -    self->priv->outgoing_cb.on_output =
> red_channel_client_on_output;
>  
>      self->priv->client_cbs.connect =
> red_channel_client_default_connect;
>      self->priv->client_cbs.disconnect =
> red_channel_client_default_disconnect;
> @@ -788,11 +780,6 @@ IncomingHandlerInterface*
> red_channel_get_incoming_handler(RedChannel *self)
>      return &self->priv->incoming_cb;
>  }
>  
> -OutgoingHandlerInterface*
> red_channel_get_outgoing_handler(RedChannel *self)
> -{
> -    return &self->priv->outgoing_cb;
> -}
> -
>  void red_channel_reset_thread_id(RedChannel *self)
>  {
>      self->priv->thread_id = pthread_self();
> diff --git a/server/red-channel.h b/server/red-channel.h
> index 291a00f..a24330a 100644
> --- a/server/red-channel.h
> +++ b/server/red-channel.h
> @@ -79,23 +79,6 @@ typedef struct IncomingHandlerInterface {
>      on_input_proc on_input;
>  } IncomingHandlerInterface;
>  
> -typedef int (*get_outgoing_msg_size_proc)(void *opaque);
> -typedef void (*prepare_outgoing_proc)(void *opaque, struct iovec
> *vec, int *vec_size, int pos);
> -typedef void (*on_outgoing_error_proc)(void *opaque);
> -typedef void (*on_outgoing_block_proc)(void *opaque);
> -typedef void (*on_outgoing_msg_done_proc)(void *opaque);
> -typedef void (*on_output_proc)(void *opaque, int n);
> -
> -typedef struct OutgoingHandlerInterface {
> -    get_outgoing_msg_size_proc get_msg_size;
> -    prepare_outgoing_proc prepare;
> -    on_outgoing_error_proc on_error;
> -    on_outgoing_block_proc on_block;
> -    on_outgoing_msg_done_proc on_msg_done;
> -    on_output_proc on_output;
> -} OutgoingHandlerInterface;
> -/* Red Channel interface */
> -
>  typedef struct RedChannel RedChannel;
>  typedef struct RedChannelClient RedChannelClient;
>  typedef struct RedClient RedClient;
> @@ -304,10 +287,9 @@ void red_channel_send_item(RedChannel *self,
> RedChannelClient *rcc, RedPipeItem
>  void red_channel_reset_thread_id(RedChannel *self);
>  StatNodeRef red_channel_get_stat_node(RedChannel *channel);
>  
> -/* FIXME: do these even need to be in RedChannel? It's really only
> used in
> +/* FIXME: does this even need to be in RedChannel? It's really only
> used in
>   * RedChannelClient. Needs refactoring */
>  IncomingHandlerInterface*
> red_channel_get_incoming_handler(RedChannel *self);
> -OutgoingHandlerInterface*
> red_channel_get_outgoing_handler(RedChannel *self);
>  
>  const RedChannelCapabilities*
> red_channel_get_local_capabilities(RedChannel *self);
>  


Not directly related to this patch, other than the fact that the patch
made me start looking into stuff a bit closer: I noticed in looking
through red_channel_client_prepare_out_msg() that we call
spice_marshaller_fill_iovec() with a hard-coded n_vec argument of
IOV_MAX. This works fine right now because OutgoingHandler::vec_buf is
defined with a size of IOV_MAX. But there's nothing preventing somebody
from calling red_channel_client_prepare_out_msg() with a smaller 'vec'
array, which always makes me just a bit nervous. Not sure we need to
fix anything here necessarily, but just thought I'd mention it.

Jonathon


More information about the Spice-devel mailing list