[Spice-devel] [PATCH spice-server] StreamDevice: move header reset to calling function

Frediano Ziglio fziglio at redhat.com
Wed Aug 30 14:43:50 UTC 2017


> 
> Right now, each handle_msg_*() function is required to reset the header
> parsing state after it is done handling the message. Although the code
> duplication is pretty minimal (just resetting hdr_pos to 0), it seems a
> bit cleaner to have the calling function
> (stream_device_read_msg_from_dev()) handle this. Change the message
> handler functions to return a boolean value that signals whether they've
> fully handled the message or not. If the return value is true, the
> calling function will reset the message parsing state so that we're
> prepared to parse the next mesage.
> ---
> 
> Proposed addition to Frediano's patch series. (Also somewhat related to
> Christophe D's question about resetting hdr_pos to 0 in patch 22)
> 

Was thinking about doing something about it.

Looks good.

I was also thinking instead of passing a SpiceCharDeviceInstance
to pass a callback to read data and stop when message data is finished
but maybe is just overkilling.

Should I squash this change along the other patches (beside last hunk) ?

Frediano

>  server/stream-device.c | 69
>  +++++++++++++++++++++++++++-----------------------
>  1 file changed, 37 insertions(+), 32 deletions(-)
> 
> diff --git a/server/stream-device.c b/server/stream-device.c
> index 3d33ca13d..a0383ae3e 100644
> --- a/server/stream-device.c
> +++ b/server/stream-device.c
> @@ -61,7 +61,7 @@ static StreamDevice
> *stream_device_new(SpiceCharDeviceInstance *sin, RedsState *
>  
>  G_DEFINE_TYPE(StreamDevice, stream_device, RED_TYPE_CHAR_DEVICE)
>  
> -typedef void StreamMsgHandler(StreamDevice *dev, SpiceCharDeviceInstance
> *sin);
> +typedef bool StreamMsgHandler(StreamDevice *dev, SpiceCharDeviceInstance
> *sin);
>  
>  static StreamMsgHandler handle_msg_format, handle_msg_data,
>  handle_msg_invalid,
>      handle_msg_cursor_set, handle_msg_cursor_move;
> @@ -72,6 +72,7 @@ stream_device_read_msg_from_dev(RedCharDevice *self,
> SpiceCharDeviceInstance *si
>      StreamDevice *dev = STREAM_DEVICE(self);
>      SpiceCharDeviceInterface *sif;
>      int n;
> +    bool handled = false;
>  
>      if (dev->has_error || dev->flow_stopped || !dev->stream_channel) {
>          return NULL;
> @@ -100,35 +101,41 @@ stream_device_read_msg_from_dev(RedCharDevice *self,
> SpiceCharDeviceInstance *si
>      switch ((StreamMsgType) dev->hdr.type) {
>      case STREAM_TYPE_FORMAT:
>          if (dev->hdr.size != sizeof(StreamMsgFormat)) {
> -            handle_msg_invalid(dev, sin);
> +            handled = handle_msg_invalid(dev, sin);
>          } else {
> -            handle_msg_format(dev, sin);
> +            handled = handle_msg_format(dev, sin);
>          }
>          break;
>      case STREAM_TYPE_DATA:
> -        handle_msg_data(dev, sin);
> +        handled = handle_msg_data(dev, sin);
>          break;
>      case STREAM_TYPE_CURSOR_SET:
> -        handle_msg_cursor_set(dev, sin);
> +        handled = handle_msg_cursor_set(dev, sin);
>          break;
>      case STREAM_TYPE_CURSOR_MOVE:
>          if (dev->hdr.size != sizeof(StreamMsgCursorMove)) {
> -            handle_msg_invalid(dev, sin);
> +            handled = handle_msg_invalid(dev, sin);
>          } else {
> -            handle_msg_cursor_move(dev, sin);
> +            handled = handle_msg_cursor_move(dev, sin);
>          }
>          break;
>      case STREAM_TYPE_CAPABILITIES:
>          /* FIXME */
>      default:
> -        handle_msg_invalid(dev, sin);
> +        handled = handle_msg_invalid(dev, sin);
>          break;
>      }
>  
> +    /* current message has been handled, so reset state and get ready to
> parse
> +     * the next message */
> +    if (handled) {
> +        dev->hdr_pos = 0;
> +    }
> +
>      return NULL;
>  }
>  
> -static void
> +static bool
>  handle_msg_invalid(StreamDevice *dev, SpiceCharDeviceInstance *sin)
>  {
>      static const char error_msg[] = "Wrong protocol";
> @@ -154,28 +161,29 @@ handle_msg_invalid(StreamDevice *dev,
> SpiceCharDeviceInstance *sin)
>      red_char_device_write_buffer_add(char_dev, buf);
>  
>      dev->has_error = true;
> +    return true;
>  }
>  
> -static void
> +static bool
>  handle_msg_format(StreamDevice *dev, SpiceCharDeviceInstance *sin)
>  {
>      StreamMsgFormat fmt;
>      SpiceCharDeviceInterface *sif = spice_char_device_get_interface(sin);
>      int n = sif->read(sin, (uint8_t *) &fmt, sizeof(fmt));
>      if (n == 0) {
> -        return;
> +        return false;
>      }
>      if (n != sizeof(fmt)) {
> -        handle_msg_invalid(dev, sin);
> -        return;
> +        return handle_msg_invalid(dev, sin);
>      }
>      fmt.width = GUINT32_FROM_LE(fmt.width);
>      fmt.height = GUINT32_FROM_LE(fmt.height);
>      stream_channel_change_format(dev->stream_channel, &fmt);
> -    dev->hdr_pos = 0;
> +
> +    return true;
>  }
>  
> -static void
> +static bool
>  handle_msg_data(StreamDevice *dev, SpiceCharDeviceInstance *sin)
>  {
>      SpiceCharDeviceInterface *sif = spice_char_device_get_interface(sin);
> @@ -193,8 +201,10 @@ handle_msg_data(StreamDevice *dev,
> SpiceCharDeviceInstance *sin)
>          dev->hdr.size -= n;
>      }
>      if (dev->hdr.size == 0) {
> -        dev->hdr_pos = 0;
> +        return true;
>      }
> +
> +    return false;
>  }
>  
>  /*
> @@ -262,7 +272,7 @@ stream_msg_cursor_set_to_cursor_cmd(const
> StreamMsgCursorSet *msg, size_t msg_si
>      return cmd;
>  }
>  
> -static void
> +static bool
>  handle_msg_cursor_set(StreamDevice *dev, SpiceCharDeviceInstance *sin)
>  {
>      const unsigned int max_cursor_set_size =
> @@ -273,45 +283,41 @@ handle_msg_cursor_set(StreamDevice *dev,
> SpiceCharDeviceInstance *sin)
>      // read part of the message till we get all
>      if (!dev->msg_buf) {
>          if (dev->hdr.size >= max_cursor_set_size || dev->hdr.size <
>          sizeof(StreamMsgCursorSet)) {
> -            handle_msg_invalid(dev, sin);
> -            return;
> +            return handle_msg_invalid(dev, sin);
>          }
>          dev->msg_buf = spice_malloc(dev->hdr.size);
>          dev->msg_len = 0;
>      }
>      int n = sif->read(sin, (uint8_t *) dev->msg_buf + dev->msg_len,
>      dev->hdr.size - dev->msg_len);
>      if (n <= 0) {
> -        return;
> +        return false;
>      }
>      dev->msg_len += n;
>      if (dev->msg_len != dev->hdr.size) {
> -        return;
> +        return false;
>      }
>  
> -    // got the full message, prepare for future message
> -    dev->hdr_pos = 0;
> -
>      // trasform the message to a cursor command and process it
>      RedCursorCmd *cmd = stream_msg_cursor_set_to_cursor_cmd(dev->msg_buf,
>      dev->msg_len);
>      if (!cmd) {
> -        handle_msg_invalid(dev, sin);
> -        return;
> +        return handle_msg_invalid(dev, sin);
>      }
>      cursor_channel_process_cmd(dev->cursor_channel, cmd);
> +
> +    return true;
>  }
>  
> -static void
> +static bool
>  handle_msg_cursor_move(StreamDevice *dev, SpiceCharDeviceInstance *sin)
>  {
>      StreamMsgCursorMove move;
>      SpiceCharDeviceInterface *sif = spice_char_device_get_interface(sin);
>      int n = sif->read(sin, (uint8_t *) &move, sizeof(move));
>      if (n == 0) {
> -        return;
> +        return false;
>      }
>      if (n != sizeof(move)) {
> -        handle_msg_invalid(dev, sin);
> -        return;
> +        return handle_msg_invalid(dev, sin);
>      }
>      move.x = GINT32_FROM_LE(move.x);
>      move.y = GINT32_FROM_LE(move.y);
> @@ -323,7 +329,7 @@ handle_msg_cursor_move(StreamDevice *dev,
> SpiceCharDeviceInstance *sin)
>  
>      cursor_channel_process_cmd(dev->cursor_channel, cmd);
>  
> -    dev->hdr_pos = 0;
> +    return true;
>  }
>  
>  static void
> @@ -482,7 +488,6 @@ stream_device_port_event(RedCharDevice *char_dev, uint8_t
> event)
>      if (device->opened) {
>          allocate_channels(device);
>      }
> -    device->hdr_pos = 0;
>      device->has_error = false;
>      device->flow_stopped = false;
>      red_char_device_reset(char_dev);


More information about the Spice-devel mailing list