[Spice-devel] [PATCH spice-server v2 1/2] red-channel: Use directly a GArray to pass capabilities

Jonathon Jongsma jjongsma at redhat.com
Wed Mar 1 17:32:09 UTC 2017


Yes. All of this duplicated code (that I wrote) has been bugging me for
quite a while. Thanks for cleaning it up.

Could you rephrase the commit summary to:
"red-channel: Use GArray directly to pass capabilities"

Acked-by: Jonathon Jongsma <jjongsma at redhat.com>



On Wed, 2017-03-01 at 13:21 +0000, Frediano Ziglio wrote:
> Capabilities where almost always passed using 2 arguments,
> a number of elements and an array but then before using
> these were converted to a GArray.
> Converting to GArray much earlier allows to easily pass
> the capabilities around.
> 
> Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
> ---
> I don't know if is worth defining an abstract type
> instead of using a simple GArray.
> Maybe a "typedef GArray RedCapabilities" could help future
> replacement of the GArray?
> On the other side this patch moves most of the array boxing
> into a single function.
> ---
>  server/cursor-channel-client.c    | 23 +++--------------------
>  server/cursor-channel-client.h    |  4 +---
>  server/cursor-channel.c           |  6 ++----
>  server/cursor-channel.h           |  9 ++++-----
>  server/dcc.c                      | 23 +++--------------------
>  server/dcc.h                      | 16 +++++-----------
>  server/inputs-channel-client.c    | 24 +++---------------------
>  server/inputs-channel-client.h    |  5 +----
>  server/inputs-channel.c           |  6 ++----
>  server/main-channel-client.c      | 23 +++--------------------
>  server/main-channel-client.h      |  3 +--
>  server/main-channel.c             |  6 ++----
>  server/main-channel.h             |  4 ++--
>  server/red-channel-client.c       | 22 +++-------------------
>  server/red-channel-client.h       |  3 +--
>  server/red-channel.c              | 10 ++++------
>  server/red-channel.h              |  7 +++----
>  server/red-qxl.c                  | 26 +++++++-------------------
>  server/red-qxl.h                  | 12 ++++--------
>  server/red-worker.c               | 13 ++++++-------
>  server/reds.c                     | 36 ++++++++++++++++++++++++++++-
> -------
>  server/smartcard-channel-client.c | 24 ++++--------------------
>  server/smartcard-channel-client.h |  4 ++--
>  server/smartcard.c                |  7 +++----
>  server/sound.c                    | 36 ++++++++---------------------
> -------
>  server/spicevmc.c                 | 10 +++++-----
>  26 files changed, 110 insertions(+), 252 deletions(-)
> 
> diff --git a/server/cursor-channel-client.c b/server/cursor-channel-
> client.c
> index 56efd1e..1344719 100644
> --- a/server/cursor-channel-client.c
> +++ b/server/cursor-channel-client.c
> @@ -93,21 +93,9 @@ void
> cursor_channel_client_migrate(RedChannelClient *rcc)
>  
>  CursorChannelClient* cursor_channel_client_new(CursorChannel
> *cursor, RedClient *client, RedsStream *stream,
>                                                 int mig_target,
> -                                               uint32_t
> *common_caps, int num_common_caps,
> -                                               uint32_t *caps, int
> num_caps)
> +                                               GArray *common_caps,
> GArray *caps)
>  {
>      CursorChannelClient *rcc;
> -    GArray *common_caps_array = NULL, *caps_array = NULL;
> -
> -    if (common_caps) {
> -        common_caps_array = g_array_sized_new(FALSE, FALSE, sizeof
> (*common_caps),
> -                                              num_common_caps);
> -        g_array_append_vals(common_caps_array, common_caps,
> num_common_caps);
> -    }
> -    if (caps) {
> -        caps_array = g_array_sized_new(FALSE, FALSE, sizeof (*caps),
> num_caps);
> -        g_array_append_vals(caps_array, caps, num_caps);
> -    }
>  
>      rcc = g_initable_new(TYPE_CURSOR_CHANNEL_CLIENT,
>                           NULL, NULL,
> @@ -115,16 +103,11 @@ CursorChannelClient*
> cursor_channel_client_new(CursorChannel *cursor, RedClient
>                           "client", client,
>                           "stream", stream,
>                           "monitor-latency", FALSE,
> -                         "common-caps", common_caps_array,
> -                         "caps", caps_array,
> +                         "common-caps", common_caps,
> +                         "caps", caps,
>                           NULL);
>      common_graphics_channel_set_during_target_migrate(COMMON_GRAPHIC
> S_CHANNEL(cursor), mig_target);
>  
> -    if (caps_array)
> -        g_array_unref(caps_array);
> -    if (common_caps_array)
> -        g_array_unref(common_caps_array);
> -
>      return rcc;
>  }
>  
> diff --git a/server/cursor-channel-client.h b/server/cursor-channel-
> client.h
> index d1dd31d..211ea94 100644
> --- a/server/cursor-channel-client.h
> +++ b/server/cursor-channel-client.h
> @@ -63,9 +63,7 @@ CursorChannelClient*
> cursor_channel_client_new(CursorChannel *cursor,
>                                                 RedClient *client,
>                                                 RedsStream *stream,
>                                                 int mig_target,
> -                                               uint32_t
> *common_caps,
> -                                               int num_common_caps,
> -                                               uint32_t *caps, int
> num_caps);
> +                                               GArray *common_caps,
> GArray *caps);
>  
>  void cursor_channel_client_reset_cursor_cache(RedChannelClient
> *rcc);
>  void cursor_channel_client_on_disconnect(RedChannelClient *rcc);
> diff --git a/server/cursor-channel.c b/server/cursor-channel.c
> index 4fe3f8d..73d7126 100644
> --- a/server/cursor-channel.c
> +++ b/server/cursor-channel.c
> @@ -406,8 +406,7 @@ void cursor_channel_set_mouse_mode(CursorChannel
> *cursor, uint32_t mode)
>  
>  void cursor_channel_connect(CursorChannel *cursor, RedClient
> *client, RedsStream *stream,
>                              int migrate,
> -                            uint32_t *common_caps, int
> num_common_caps,
> -                            uint32_t *caps, int num_caps)
> +                            GArray *common_caps, GArray *caps)
>  {
>      CursorChannelClient *ccc;
>  
> @@ -416,8 +415,7 @@ void cursor_channel_connect(CursorChannel
> *cursor, RedClient *client, RedsStream
>      spice_info("add cursor channel client");
>      ccc = cursor_channel_client_new(cursor, client, stream,
>                                      migrate,
> -                                    common_caps, num_common_caps,
> -                                    caps, num_caps);
> +                                    common_caps, caps);
>      spice_return_if_fail(ccc != NULL);
>  
>      RedChannelClient *rcc = RED_CHANNEL_CLIENT(ccc);
> diff --git a/server/cursor-channel.h b/server/cursor-channel.h
> index ec9d44f..2c3948d 100644
> --- a/server/cursor-channel.h
> +++ b/server/cursor-channel.h
> @@ -72,11 +72,10 @@
> void                 cursor_channel_set_mouse_mode(CursorChannel
> *cursor, uint32
>   * This is the equivalent of RedChannel client connect callback.
>   * See comment on cursor_channel_new.
>   */
> -void                 cursor_channel_connect     (CursorChannel
> *cursor, RedClient *client,
> -                                                 RedsStream *stream,
> -                                                 int migrate,
> -                                                 uint32_t
> *common_caps, int num_common_caps,
> -                                                 uint32_t *caps, int
> num_caps);
> +void cursor_channel_connect(CursorChannel *cursor, RedClient
> *client,
> +                            RedsStream *stream,
> +                            int migrate,
> +                            GArray *common_caps, GArray *caps);
>  
>  /**
>   * Migrate a client channel from a CursorChannel.
> diff --git a/server/dcc.c b/server/dcc.c
> index 373dad9..3cc9573 100644
> --- a/server/dcc.c
> +++ b/server/dcc.c
> @@ -482,25 +482,13 @@ static void
> dcc_init_stream_agents(DisplayChannelClient *dcc)
>  DisplayChannelClient *dcc_new(DisplayChannel *display,
>                                RedClient *client, RedsStream *stream,
>                                int mig_target,
> -                              uint32_t *common_caps, int
> num_common_caps,
> -                              uint32_t *caps, int num_caps,
> +                              GArray *common_caps, GArray *caps,
>                                SpiceImageCompression
> image_compression,
>                                spice_wan_compression_t jpeg_state,
>                                spice_wan_compression_t
> zlib_glz_state)
>  
>  {
>      DisplayChannelClient *dcc;
> -    GArray *common_caps_array = NULL, *caps_array = NULL;
> -
> -    if (common_caps) {
> -        common_caps_array = g_array_sized_new(FALSE, FALSE, sizeof
> (*common_caps),
> -                                              num_common_caps);
> -        g_array_append_vals(common_caps_array, common_caps,
> num_common_caps);
> -    }
> -    if (caps) {
> -        caps_array = g_array_sized_new(FALSE, FALSE, sizeof (*caps),
> num_caps);
> -        g_array_append_vals(caps_array, caps, num_caps);
> -    }
>  
>      dcc = g_initable_new(TYPE_DISPLAY_CHANNEL_CLIENT,
>                           NULL, NULL,
> @@ -508,8 +496,8 @@ DisplayChannelClient *dcc_new(DisplayChannel
> *display,
>                           "client", client,
>                           "stream", stream,
>                           "monitor-latency", TRUE,
> -                         "common-caps", common_caps_array,
> -                         "caps", caps_array,
> +                         "common-caps", common_caps,
> +                         "caps", caps,
>                           "image-compression", image_compression,
>                           "jpeg-state", jpeg_state,
>                           "zlib-glz-state", zlib_glz_state,
> @@ -518,11 +506,6 @@ DisplayChannelClient *dcc_new(DisplayChannel
> *display,
>      common_graphics_channel_set_during_target_migrate(COMMON_GRAPHIC
> S_CHANNEL(display), mig_target);
>      dcc->priv->id =
> common_graphics_channel_get_qxl(COMMON_GRAPHICS_CHANNEL(display))-
> >id;
>  
> -    if (common_caps_array)
> -        g_array_unref(common_caps_array);
> -    if (caps_array)
> -        g_array_unref(caps_array);
> -
>      return dcc;
>  }
>  
> diff --git a/server/dcc.h b/server/dcc.h
> index ebdbb8d..19416e3 100644
> --- a/server/dcc.h
> +++ b/server/dcc.h
> @@ -130,17 +130,11 @@ typedef struct RedDrawablePipeItem {
>      DisplayChannelClient *dcc;
>  } RedDrawablePipeItem;
>  
> -DisplayChannelClient*      dcc_new                                  
>  (DisplayChannel *display,
> -                                                                    
>   RedClient *client,
> -                                                                    
>   RedsStream *stream,
> -                                                                    
>   int mig_target,
> -                                                                    
>   uint32_t *common_caps,
> -                                                                    
>   int num_common_caps,
> -                                                                    
>   uint32_t *caps,
> -                                                                    
>   int num_caps,
> -                                                                    
>   SpiceImageCompression image_compression,
> -                                                                    
>   spice_wan_compression_t jpeg_state,
> -                                                                    
>   spice_wan_compression_t zlib_glz_state);
> +DisplayChannelClient* dcc_new(DisplayChannel *display, RedClient
> *client, RedsStream *stream,
> +                              int mig_target, GArray *common_caps,
> GArray *caps,
> +                              SpiceImageCompression
> image_compression,
> +                              spice_wan_compression_t jpeg_state,
> +                              spice_wan_compression_t
> zlib_glz_state);
>  void                       dcc_start                                
>  (DisplayChannelClient *dcc);
>  void                       dcc_stop                                 
>  (DisplayChannelClient *dcc);
>  int                        dcc_handle_message                       
>  (RedChannelClient *rcc,
> diff --git a/server/inputs-channel-client.c b/server/inputs-channel-
> client.c
> index 4a534e8..c8d33ba 100644
> --- a/server/inputs-channel-client.c
> +++ b/server/inputs-channel-client.c
> @@ -48,38 +48,20 @@ RedChannelClient*
> inputs_channel_client_create(RedChannel *channel,
>                                                 RedClient *client,
>                                                 RedsStream *stream,
>                                                 int monitor_latency,
> -                                               int num_common_caps,
> -                                               uint32_t
> *common_caps,
> -                                               int num_caps,
> -                                               uint32_t *caps)
> +                                               GArray *common_caps,
> GArray *caps)
>  {
>      RedChannelClient *rcc;
> -    GArray *common_caps_array = NULL, *caps_array = NULL;
>  
> -    if (common_caps) {
> -        common_caps_array = g_array_sized_new(FALSE, FALSE, sizeof
> (*common_caps),
> -                                              num_common_caps);
> -        g_array_append_vals(common_caps_array, common_caps,
> num_common_caps);
> -    }
> -    if (caps) {
> -        caps_array = g_array_sized_new(FALSE, FALSE, sizeof (*caps),
> num_caps);
> -        g_array_append_vals(caps_array, caps, num_caps);
> -    }
>      rcc = g_initable_new(TYPE_INPUTS_CHANNEL_CLIENT,
>                           NULL, NULL,
>                           "channel", channel,
>                           "client", client,
>                           "stream", stream,
>                           "monitor-latency", monitor_latency,
> -                         "caps", caps_array,
> -                         "common-caps", common_caps_array,
> +                         "caps", caps,
> +                         "common-caps", common_caps,
>                           NULL);
>  
> -    if (caps_array)
> -        g_array_unref(caps_array);
> -    if (common_caps_array)
> -        g_array_unref(common_caps_array);
> -
>      return rcc;
>  }
>  
> diff --git a/server/inputs-channel-client.h b/server/inputs-channel-
> client.h
> index 7550b3c..a856a58 100644
> --- a/server/inputs-channel-client.h
> +++ b/server/inputs-channel-client.h
> @@ -60,10 +60,7 @@ RedChannelClient*
> inputs_channel_client_create(RedChannel *channel,
>                                                 RedClient *client,
>                                                 RedsStream *stream,
>                                                 int monitor_latency,
> -                                               int num_common_caps,
> -                                               uint32_t
> *common_caps,
> -                                               int num_caps,
> -                                               uint32_t *caps);
> +                                               GArray *common_caps,
> GArray *caps);
>  
>  uint16_t inputs_channel_client_get_motion_count(InputsChannelClient*
> self);
>  /* only for migration */
> diff --git a/server/inputs-channel.c b/server/inputs-channel.c
> index ed92e71..cd92e1a 100644
> --- a/server/inputs-channel.c
> +++ b/server/inputs-channel.c
> @@ -486,8 +486,7 @@ static void inputs_pipe_add_init(RedChannelClient
> *rcc)
>  
>  static void inputs_connect(RedChannel *channel, RedClient *client,
>                             RedsStream *stream, int migration,
> -                           int num_common_caps, uint32_t
> *common_caps,
> -                           int num_caps, uint32_t *caps)
> +                           GArray *common_caps, GArray *caps)
>  {
>      RedChannelClient *rcc;
>  
> @@ -498,8 +497,7 @@ static void inputs_connect(RedChannel *channel,
> RedClient *client,
>  
>      spice_printerr("inputs channel client create");
>      rcc = inputs_channel_client_create(channel, client, stream,
> FALSE,
> -                                       num_common_caps, common_caps,
> -                                       num_caps, caps);
> +                                       common_caps, caps);
>      if (!rcc) {
>          return;
>      }
> diff --git a/server/main-channel-client.c b/server/main-channel-
> client.c
> index 6aace29..c8e01bc 100644
> --- a/server/main-channel-client.c
> +++ b/server/main-channel-client.c
> @@ -651,21 +651,9 @@ static void ping_timer_cb(void *opaque)
>  
>  MainChannelClient *main_channel_client_create(MainChannel
> *main_chan, RedClient *client,
>                                                RedsStream *stream,
> uint32_t connection_id,
> -                                              int num_common_caps,
> uint32_t *common_caps,
> -                                              int num_caps, uint32_t
> *caps)
> +                                              GArray *common_caps,
> GArray *caps)
>  {
>      MainChannelClient *mcc;
> -    GArray *common_caps_array = NULL, *caps_array = NULL;
> -
> -    if (common_caps) {
> -        common_caps_array = g_array_sized_new(FALSE, FALSE, sizeof
> (*common_caps),
> -                                              num_common_caps);
> -        g_array_append_vals(common_caps_array, common_caps,
> num_common_caps);
> -    }
> -    if (caps) {
> -        caps_array = g_array_sized_new(FALSE, FALSE, sizeof (*caps),
> num_caps);
> -        g_array_append_vals(caps_array, caps, num_caps);
> -    }
>  
>      mcc = g_initable_new(TYPE_MAIN_CHANNEL_CLIENT,
>                           NULL, NULL,
> @@ -673,16 +661,11 @@ MainChannelClient
> *main_channel_client_create(MainChannel *main_chan, RedClient
>                           "client", client,
>                           "stream", stream,
>                           "monitor-latency", FALSE,
> -                         "caps", caps_array,
> -                         "common-caps", common_caps_array,
> +                         "caps", caps,
> +                         "common-caps", common_caps,
>                           "connection-id", connection_id,
>                           NULL);
>  
> -    if (caps_array)
> -        g_array_unref(caps_array);
> -    if (common_caps_array)
> -        g_array_unref(common_caps_array);
> -
>      return mcc;
>  }
>  
> diff --git a/server/main-channel-client.h b/server/main-channel-
> client.h
> index 14fb419..5cb2aad 100644
> --- a/server/main-channel-client.h
> +++ b/server/main-channel-client.h
> @@ -58,8 +58,7 @@ GType main_channel_client_get_type(void)
> G_GNUC_CONST;
>  
>  MainChannelClient *main_channel_client_create(MainChannel
> *main_chan, RedClient *client,
>                                                RedsStream *stream,
> uint32_t connection_id,
> -                                              int num_common_caps,
> uint32_t *common_caps,
> -                                              int num_caps, uint32_t
> *caps);
> +                                              GArray *common_caps,
> GArray *caps);
>  
>  void main_channel_client_push_agent_tokens(MainChannelClient *mcc,
> uint32_t num_tokens);
>  void main_channel_client_push_agent_data(MainChannelClient *mcc,
> uint8_t* data, size_t len,
> diff --git a/server/main-channel.c b/server/main-channel.c
> index 3a6e6cd..7912ced 100644
> --- a/server/main-channel.c
> +++ b/server/main-channel.c
> @@ -287,8 +287,7 @@ static int
> main_channel_handle_migrate_flush_mark(RedChannelClient *rcc)
>  
>  MainChannelClient *main_channel_link(MainChannel *channel, RedClient
> *client,
>                                       RedsStream *stream, uint32_t
> connection_id, int migration,
> -                                     int num_common_caps, uint32_t
> *common_caps, int num_caps,
> -                                     uint32_t *caps)
> +                                     GArray *common_caps, GArray
> *caps)
>  {
>      MainChannelClient *mcc;
>  
> @@ -299,8 +298,7 @@ MainChannelClient *main_channel_link(MainChannel
> *channel, RedClient *client,
>      // former glory)
>      spice_printerr("add main channel client");
>      mcc = main_channel_client_create(channel, client, stream,
> connection_id,
> -                                     num_common_caps, common_caps,
> -                                     num_caps, caps);
> +                                     common_caps, caps);
>      return mcc;
>  }
>  
> diff --git a/server/main-channel.h b/server/main-channel.h
> index b70649c..5992f1c 100644
> --- a/server/main-channel.h
> +++ b/server/main-channel.h
> @@ -59,8 +59,8 @@ MainChannel *main_channel_new(RedsState *reds);
>  RedClient *main_channel_get_client_by_link_id(MainChannel
> *main_chan, uint32_t link_id);
>  /* This is a 'clone' from the reds.h Channel.link callback to allow
> passing link_id */
>  MainChannelClient *main_channel_link(MainChannel *, RedClient
> *client,
> -     RedsStream *stream, uint32_t link_id, int migration, int
> num_common_caps,
> -     uint32_t *common_caps, int num_caps, uint32_t *caps);
> +     RedsStream *stream, uint32_t link_id, int migration,
> +     GArray *common_caps, GArray *caps);
>  void main_channel_push_mouse_mode(MainChannel *main_chan, int
> current_mode, int is_client_mouse_allowed);
>  void main_channel_push_agent_connected(MainChannel *main_chan);
>  void main_channel_push_agent_disconnected(MainChannel *main_chan);
> diff --git a/server/red-channel-client.c b/server/red-channel-
> client.c
> index b583da2..0100af7 100644
> --- a/server/red-channel-client.c
> +++ b/server/red-channel-client.c
> @@ -1013,36 +1013,20 @@ cleanup:
>  RedChannelClient *red_channel_client_create(RedChannel *channel,
> RedClient *client,
>                                              RedsStream *stream,
>                                              int monitor_latency,
> -                                            int num_common_caps,
> uint32_t *common_caps,
> -                                            int num_caps, uint32_t
> *caps)
> +                                            GArray *common_caps,
> GArray *caps)
>  {
>      RedChannelClient *rcc;
> -    GArray *common_caps_array = NULL, *caps_array = NULL;
>  
> -    if (common_caps) {
> -        common_caps_array = g_array_sized_new(FALSE, FALSE, sizeof
> (*common_caps),
> -                                              num_common_caps);
> -        g_array_append_vals(common_caps_array, common_caps,
> num_common_caps);
> -    }
> -    if (caps) {
> -        caps_array = g_array_sized_new(FALSE, FALSE, sizeof (*caps),
> num_caps);
> -        g_array_append_vals(caps_array, caps, num_caps);
> -    }
>      rcc = g_initable_new(RED_TYPE_CHANNEL_CLIENT,
>                           NULL, NULL,
>                           "channel", channel,
>                           "client", client,
>                           "stream", stream,
>                           "monitor-latency", monitor_latency,
> -                         "caps", caps_array,
> -                         "common-caps", common_caps_array,
> +                         "caps", caps,
> +                         "common-caps", common_caps,
>                           NULL);
>  
> -    if (caps_array)
> -        g_array_unref(caps_array);
> -    if (common_caps_array)
> -        g_array_unref(common_caps_array);
> -
>      return rcc;
>  }
>  
> diff --git a/server/red-channel-client.h b/server/red-channel-
> client.h
> index 474a5cd..f5be4a1 100644
> --- a/server/red-channel-client.h
> +++ b/server/red-channel-client.h
> @@ -50,8 +50,7 @@ GType red_channel_client_get_type(void)
> G_GNUC_CONST;
>  RedChannelClient *red_channel_client_create(RedChannel *channel,
>                                              RedClient *client,
> RedsStream *stream,
>                                              int monitor_latency,
> -                                            int num_common_caps,
> uint32_t *common_caps,
> -                                            int num_caps, uint32_t
> *caps);
> +                                            GArray *common_caps,
> GArray *caps);
>  
>  gboolean red_channel_client_is_connected(RedChannelClient *rcc);
>  void red_channel_client_default_migrate(RedChannelClient *rcc);
> diff --git a/server/red-channel.c b/server/red-channel.c
> index 67a570d..56fa4fc 100644
> --- a/server/red-channel.c
> +++ b/server/red-channel.c
> @@ -219,8 +219,7 @@ red_channel_constructed(GObject *object)
>  static void red_channel_client_default_connect(RedChannel *channel,
> RedClient *client,
>                                                 RedsStream *stream,
>                                                 int migration,
> -                                               int num_common_caps,
> uint32_t *common_caps,
> -                                               int num_caps,
> uint32_t *caps)
> +                                               GArray *common_caps,
> GArray *caps)
>  {
>      spice_error("not implemented");
>  }
> @@ -513,12 +512,11 @@ void red_channel_disconnect(RedChannel
> *channel)
>  }
>  
>  void red_channel_connect(RedChannel *channel, RedClient *client,
> -                         RedsStream *stream, int migration, int
> num_common_caps,
> -                         uint32_t *common_caps, int num_caps,
> uint32_t *caps)
> +                         RedsStream *stream, int migration,
> +                         GArray *common_caps, GArray *caps)
>  {
>      channel->priv->client_cbs.connect(channel, client, stream,
> migration,
> -                                      num_common_caps, common_caps,
> num_caps,
> -                                      caps);
> +                                      common_caps, caps);
>  }
>  
>  void red_channel_apply_clients(RedChannel *channel,
> channel_client_callback cb)
> diff --git a/server/red-channel.h b/server/red-channel.h
> index 79aee01..b20e254 100644
> --- a/server/red-channel.h
> +++ b/server/red-channel.h
> @@ -60,8 +60,7 @@ typedef uint64_t
> (*channel_handle_migrate_data_get_serial_proc)(RedChannelClient
>  
>  
>  typedef void (*channel_client_connect_proc)(RedChannel *channel,
> RedClient *client, RedsStream *stream,
> -                                            int migration, int
> num_common_caps, uint32_t *common_caps,
> -                                            int num_caps, uint32_t
> *caps);
> +                                            int migration, GArray
> *common_caps, GArray *caps);
>  typedef void (*channel_client_disconnect_proc)(RedChannelClient
> *base);
>  typedef void (*channel_client_migrate_proc)(RedChannelClient *base);
>  
> @@ -215,8 +214,8 @@ void red_channel_send(RedChannel *channel);
>  // For red_worker
>  void red_channel_disconnect(RedChannel *channel);
>  void red_channel_connect(RedChannel *channel, RedClient *client,
> -                         RedsStream *stream, int migration, int
> num_common_caps,
> -                         uint32_t *common_caps, int num_caps,
> uint32_t *caps);
> +                         RedsStream *stream, int migration,
> +                         GArray *common_caps, GArray *caps);
>  
>  /* return the sum of all the rcc pipe size */
>  uint32_t red_channel_max_pipe_size(RedChannel *channel);
> diff --git a/server/red-qxl.c b/server/red-qxl.c
> index b6b3770..12ae87f 100644
> --- a/server/red-qxl.c
> +++ b/server/red-qxl.c
> @@ -76,8 +76,7 @@ int red_qxl_check_qxl_version(QXLInstance *qxl, int
> major, int minor)
>  
>  static void red_qxl_set_display_peer(RedChannel *channel, RedClient
> *client,
>                                       RedsStream *stream, int
> migration,
> -                                     int num_common_caps, uint32_t
> *common_caps, int num_caps,
> -                                     uint32_t *caps)
> +                                     GArray *common_caps, GArray
> *caps)
>  {
>      RedWorkerMessageDisplayConnect payload = {0,};
>      Dispatcher *dispatcher;
> @@ -87,13 +86,8 @@ static void red_qxl_set_display_peer(RedChannel
> *channel, RedClient *client,
>      payload.client = client;
>      payload.stream = stream;
>      payload.migration = migration;
> -    payload.num_common_caps = num_common_caps;
> -    payload.common_caps =
> spice_malloc(sizeof(uint32_t)*num_common_caps);
> -    payload.num_caps = num_caps;
> -    payload.caps = spice_malloc(sizeof(uint32_t)*num_caps);
> -
> -    memcpy(payload.common_caps, common_caps,
> sizeof(uint32_t)*num_common_caps);
> -    memcpy(payload.caps, caps, sizeof(uint32_t)*num_caps);
> +    payload.common_caps = g_array_ref(common_caps);
> +    payload.caps = g_array_ref(caps);
>  
>      dispatcher_send_message(dispatcher,
>                              RED_WORKER_MESSAGE_DISPLAY_CONNECT,
> @@ -142,9 +136,8 @@ static void
> red_qxl_display_migrate(RedChannelClient *rcc)
>  }
>  
>  static void red_qxl_set_cursor_peer(RedChannel *channel, RedClient
> *client, RedsStream *stream,
> -                                    int migration, int
> num_common_caps,
> -                                    uint32_t *common_caps, int
> num_caps,
> -                                    uint32_t *caps)
> +                                    int migration,
> +                                    GArray *common_caps, GArray
> *caps)
>  {
>      RedWorkerMessageCursorConnect payload = {0,};
>      Dispatcher *dispatcher = (Dispatcher
> *)g_object_get_data(G_OBJECT(channel), "dispatcher");
> @@ -152,13 +145,8 @@ static void red_qxl_set_cursor_peer(RedChannel
> *channel, RedClient *client, Reds
>      payload.client = client;
>      payload.stream = stream;
>      payload.migration = migration;
> -    payload.num_common_caps = num_common_caps;
> -    payload.common_caps =
> spice_malloc(sizeof(uint32_t)*num_common_caps);
> -    payload.num_caps = num_caps;
> -    payload.caps = spice_malloc(sizeof(uint32_t)*num_caps);
> -
> -    memcpy(payload.common_caps, common_caps,
> sizeof(uint32_t)*num_common_caps);
> -    memcpy(payload.caps, caps, sizeof(uint32_t)*num_caps);
> +    payload.common_caps = g_array_ref(common_caps);
> +    payload.caps = g_array_ref(caps);
>  
>      dispatcher_send_message(dispatcher,
>                              RED_WORKER_MESSAGE_CURSOR_CONNECT,
> diff --git a/server/red-qxl.h b/server/red-qxl.h
> index 0c9498a..4d3c3de 100644
> --- a/server/red-qxl.h
> +++ b/server/red-qxl.h
> @@ -126,11 +126,9 @@ enum {
>  typedef struct RedWorkerMessageDisplayConnect {
>      RedClient * client;
>      RedsStream * stream;
> -    uint32_t *common_caps; // red_worker should free
> -    uint32_t *caps;        // red_worker should free
> +    GArray *common_caps; // red_worker should release
> +    GArray *caps;        // red_worker should release
>      int migration;
> -    int num_common_caps;
> -    int num_caps;
>  } RedWorkerMessageDisplayConnect;
>  
>  typedef struct RedWorkerMessageDisplayDisconnect {
> @@ -145,10 +143,8 @@ typedef struct RedWorkerMessageCursorConnect {
>      RedClient *client;
>      RedsStream *stream;
>      int migration;
> -    uint32_t *common_caps; // red_worker should free
> -    int num_common_caps;
> -    uint32_t *caps;        // red_worker should free
> -    int num_caps;
> +    GArray *common_caps; // red_worker should release
> +    GArray *caps;        // red_worker should release
>  } RedWorkerMessageCursorConnect;
>  
>  typedef struct RedWorkerMessageCursorDisconnect {
> diff --git a/server/red-worker.c b/server/red-worker.c
> index e5adbaa..779a6c1 100644
> --- a/server/red-worker.c
> +++ b/server/red-worker.c
> @@ -736,7 +736,7 @@ static void handle_dev_display_connect(void
> *opaque, void *payload)
>      spice_return_if_fail(display);
>  
>      dcc = dcc_new(display, msg->client, msg->stream, msg->migration,
> -                  msg->common_caps, msg->num_common_caps, msg->caps, 
> msg->num_caps,
> +                  msg->common_caps, msg->caps,
>                    worker->image_compression, worker->jpeg_state,
> worker->zlib_glz_state);
>      if (!dcc) {
>          return;
> @@ -745,8 +745,8 @@ static void handle_dev_display_connect(void
> *opaque, void *payload)
>      guest_set_client_capabilities(worker);
>      dcc_start(dcc);
>  
> -    free(msg->caps);
> -    free(msg->common_caps);
> +    g_array_unref(msg->caps);
> +    g_array_unref(msg->common_caps);
>  }
>  
>  static void handle_dev_display_disconnect(void *opaque, void
> *payload)
> @@ -832,10 +832,9 @@ static void handle_dev_cursor_connect(void
> *opaque, void *payload)
>      spice_info("cursor connect");
>      cursor_channel_connect(worker->cursor_channel,
>                             msg->client, msg->stream, msg->migration,
> -                           msg->common_caps, msg->num_common_caps,
> -                           msg->caps, msg->num_caps);
> -    free(msg->caps);
> -    free(msg->common_caps);
> +                           msg->common_caps, msg->caps);
> +    g_array_unref(msg->caps);
> +    g_array_unref(msg->common_caps);
>  }
>  
>  static void handle_dev_cursor_disconnect(void *opaque, void
> *payload)
> diff --git a/server/reds.c b/server/reds.c
> index 898be92..ff98a48 100644
> --- a/server/reds.c
> +++ b/server/reds.c
> @@ -1675,6 +1675,24 @@ static RedClient *reds_get_client(RedsState
> *reds)
>      return reds->clients->data;
>  }
>  
> +static GArray *reds_caps_new(const uint32_t *caps, size_t num_caps)
> +{
> +    if (caps == NULL || num_caps == 0) {
> +        return NULL;
> +    }
> +
> +    GArray *array = g_array_sized_new(FALSE, FALSE, sizeof (*caps),
> num_caps);
> +    g_array_append_vals(array, caps, num_caps);
> +    return array;
> +}
> +
> +static inline void reds_caps_unref(GArray *caps)
> +{
> +    if (caps) {
> +        g_array_unref(caps);
> +    }
> +}
> +
>  // TODO: now that main is a separate channel this should
>  // actually be joined with reds_handle_other_links, become
> reds_handle_link
>  static void reds_handle_main_link(RedsState *reds, RedLinkInfo
> *link)
> @@ -1720,11 +1738,13 @@ static void reds_handle_main_link(RedsState
> *reds, RedLinkInfo *link)
>      caps = (uint32_t *)((uint8_t *)link_mess + link_mess-
> >caps_offset);
>      client = red_client_new(reds, mig_target);
>      reds->clients = g_list_prepend(reds->clients, client);
> +    GArray *common_caps = reds_caps_new(caps, link_mess-
> >num_common_caps);
> +    GArray *channel_caps = reds_caps_new(caps + link_mess-
> >num_common_caps, link_mess->num_channel_caps);
>      mcc = main_channel_link(reds->main_channel, client,
>                              stream, connection_id, mig_target,
> -                            link_mess->num_common_caps,
> -                            link_mess->num_common_caps ? caps :
> NULL, link_mess->num_channel_caps,
> -                            link_mess->num_channel_caps ? caps +
> link_mess->num_common_caps : NULL);
> +                            common_caps, channel_caps);
> +    reds_caps_unref(common_caps);
> +    reds_caps_unref(channel_caps);
>      spice_info("NEW Client %p mcc %p connect-id %d", client, mcc,
> connection_id);
>      free(link_mess);
>      red_client_set_main(client, mcc);
> @@ -1791,13 +1811,13 @@ static void reds_channel_do_link(RedChannel
> *channel, RedClient *client,
>      spice_assert(stream);
>  
>      caps = (uint32_t *)((uint8_t *)link_msg + link_msg-
> >caps_offset);
> +    GArray *common_caps = reds_caps_new(caps, link_msg-
> >num_common_caps);
> +    GArray *channel_caps = reds_caps_new(caps + link_msg-
> >num_common_caps, link_msg->num_channel_caps);
>      red_channel_connect(channel, client, stream,
>                          red_client_during_migrate_at_target(client),
> -                        link_msg->num_common_caps,
> -                        link_msg->num_common_caps ? caps : NULL,
> -                        link_msg->num_channel_caps,
> -                        link_msg->num_channel_caps ?
> -                        caps + link_msg->num_common_caps : NULL);
> +                        common_caps, channel_caps);
> +    reds_caps_unref(common_caps);
> +    reds_caps_unref(channel_caps);
>  }
>  
>  /*
> diff --git a/server/smartcard-channel-client.c b/server/smartcard-
> channel-client.c
> index 6234844..2c99309 100644
> --- a/server/smartcard-channel-client.c
> +++ b/server/smartcard-channel-client.c
> @@ -103,21 +103,10 @@
> smart_card_channel_client_init(SmartCardChannelClient *self)
>  SmartCardChannelClient* smartcard_channel_client_create(RedChannel
> *channel,
>                                                          RedClient
> *client, RedsStream *stream,
>                                                          int
> monitor_latency,
> -                                                        int
> num_common_caps, uint32_t *common_caps,
> -                                                        int
> num_caps, uint32_t *caps)
> +                                                        GArray
> *common_caps,
> +                                                        GArray
> *caps)
>  {
>      SmartCardChannelClient *rcc;
> -    GArray *common_caps_array = NULL, *caps_array = NULL;
> -
> -    if (common_caps) {
> -        common_caps_array = g_array_sized_new(FALSE, FALSE, sizeof
> (*common_caps),
> -                                              num_common_caps);
> -        g_array_append_vals(common_caps_array, common_caps,
> num_common_caps);
> -    }
> -    if (caps) {
> -        caps_array = g_array_sized_new(FALSE, FALSE, sizeof (*caps),
> num_caps);
> -        g_array_append_vals(caps_array, caps, num_caps);
> -    }
>  
>      rcc = g_initable_new(TYPE_SMARTCARD_CHANNEL_CLIENT,
>                           NULL, NULL,
> @@ -125,15 +114,10 @@ SmartCardChannelClient*
> smartcard_channel_client_create(RedChannel *channel,
>                           "client", client,
>                           "stream", stream,
>                           "monitor-latency", monitor_latency,
> -                         "caps", caps_array,
> -                         "common-caps", common_caps_array,
> +                         "caps", caps,
> +                         "common-caps", common_caps,
>                           NULL);
>  
> -    if (caps_array)
> -        g_array_unref(caps_array);
> -    if (common_caps_array)
> -        g_array_unref(common_caps_array);
> -
>      return rcc;
>  }
>  
> diff --git a/server/smartcard-channel-client.h b/server/smartcard-
> channel-client.h
> index 9350d7a..56e36ec 100644
> --- a/server/smartcard-channel-client.h
> +++ b/server/smartcard-channel-client.h
> @@ -58,8 +58,8 @@ GType smart_card_channel_client_get_type(void)
> G_GNUC_CONST;
>  SmartCardChannelClient* smartcard_channel_client_create(RedChannel
> *channel,
>                                                          RedClient
> *client, RedsStream *stream,
>                                                          int
> monitor_latency,
> -                                                        int
> num_common_caps, uint32_t *common_caps,
> -                                                        int
> num_caps, uint32_t *caps);
> +                                                        GArray
> *common_caps,
> +                                                        GArray
> *caps);
>  
>  uint8_t* smartcard_channel_client_alloc_msg_rcv_buf(RedChannelClient
> *rcc,
>                                                      uint16_t type,
> diff --git a/server/smartcard.c b/server/smartcard.c
> index 8f12fd9..b444e4d 100644
> --- a/server/smartcard.c
> +++ b/server/smartcard.c
> @@ -528,8 +528,7 @@ int
> smartcard_char_device_handle_migrate_data(RedCharDeviceSmartcard
> *smartcard,
>  
>  static void smartcard_connect_client(RedChannel *channel, RedClient
> *client,
>                                       RedsStream *stream, int
> migration,
> -                                     int num_common_caps, uint32_t
> *common_caps,
> -                                     int num_caps, uint32_t *caps)
> +                                     GArray *common_caps, GArray
> *caps)
>  {
>      SpiceCharDeviceInstance *char_device =
>              smartcard_readers_get_unattached();
> @@ -540,8 +539,8 @@ static void smartcard_connect_client(RedChannel
> *channel, RedClient *client,
>                                            client,
>                                            stream,
>                                            FALSE,
> -                                          num_common_caps,
> common_caps,
> -                                          num_caps, caps);
> +                                          common_caps,
> +                                          caps);
>  
>      if (!scc) {
>          return;
> diff --git a/server/sound.c b/server/sound.c
> index faaeb29..e41ab1e 100644
> --- a/server/sound.c
> +++ b/server/sound.c
> @@ -1079,11 +1079,9 @@ playback_channel_client_constructed(GObject
> *object)
>  }
>  
>  static void snd_set_peer(RedChannel *red_channel, RedClient *client,
> RedsStream *stream,
> -                         int num_common_caps, uint32_t *common_caps,
> -                         int num_caps, uint32_t *caps, GType type)
> +                         GArray *common_caps, GArray *caps, GType
> type)
>  {
>      SndChannel *channel = SND_CHANNEL(red_channel);
> -    GArray *common_caps_array = NULL, *caps_array = NULL;
>      SndChannelClient *snd_client;
>  
>      if (channel->connection) {
> @@ -1091,40 +1089,23 @@ static void snd_set_peer(RedChannel
> *red_channel, RedClient *client, RedsStream
>          channel->connection = NULL;
>      }
>  
> -    if (common_caps) {
> -        common_caps_array = g_array_sized_new(FALSE, FALSE, sizeof
> (*common_caps),
> -                                              num_common_caps);
> -        g_array_append_vals(common_caps_array, common_caps,
> num_common_caps);
> -    }
> -    if (caps) {
> -        caps_array = g_array_sized_new(FALSE, FALSE, sizeof (*caps),
> num_caps);
> -        g_array_append_vals(caps_array, caps, num_caps);
> -    }
> -
>      snd_client = g_initable_new(type,
>                                  NULL, NULL,
>                                  "channel", channel,
>                                  "client", client,
>                                  "stream", stream,
> -                                "caps", caps_array,
> -                                "common-caps", common_caps_array,
> +                                "caps", caps,
> +                                "common-caps", common_caps,
>                                  NULL);
>      g_warn_if_fail(snd_client != NULL);
> -
> -    if (caps_array) {
> -        g_array_unref(caps_array);
> -    }
> -    if (common_caps_array) {
> -        g_array_unref(common_caps_array);
> -    }
>  }
>  
>  static void snd_set_playback_peer(RedChannel *red_channel, RedClient
> *client, RedsStream *stream,
> -                                  G_GNUC_UNUSED int migration, int
> num_common_caps, uint32_t *common_caps,
> -                                  int num_caps, uint32_t *caps)
> +                                  G_GNUC_UNUSED int migration,
> +                                  GArray *common_caps, GArray *caps)
>  {
>      snd_set_peer(red_channel, client, stream,
> -                 num_common_caps, common_caps, num_caps, caps,
> +                 common_caps, caps,
>                   TYPE_PLAYBACK_CHANNEL_CLIENT);
>  }
>  
> @@ -1302,11 +1283,10 @@ record_channel_client_constructed(GObject
> *object)
>  
>  static void snd_set_record_peer(RedChannel *red_channel, RedClient
> *client, RedsStream *stream,
>                                  G_GNUC_UNUSED int migration,
> -                                int num_common_caps, uint32_t
> *common_caps,
> -                                int num_caps, uint32_t *caps)
> +                                GArray *common_caps, GArray *caps)
>  {
>      snd_set_peer(red_channel, client, stream,
> -                 num_common_caps, common_caps, num_caps, caps,
> +                 common_caps, caps,
>                   TYPE_RECORD_CHANNEL_CLIENT);
>  }
>  
> diff --git a/server/spicevmc.c b/server/spicevmc.c
> index abb0b52..d35a473 100644
> --- a/server/spicevmc.c
> +++ b/server/spicevmc.c
> @@ -182,8 +182,8 @@ static void
> red_vmc_channel_port_init(RedVmcChannelPort *self)
>  G_DEFINE_TYPE(RedVmcChannelPort, red_vmc_channel_port,
> RED_TYPE_VMC_CHANNEL)
>  
>  static void spicevmc_connect(RedChannel *channel, RedClient *client,
> -                             RedsStream *stream, int migration, int
> num_common_caps,
> -                             uint32_t *common_caps, int num_caps,
> uint32_t *caps);
> +                             RedsStream *stream, int migration,
> +                             GArray *common_caps, GArray *caps);
>  
>  static void
>  red_vmc_channel_constructed(GObject *object)
> @@ -764,8 +764,8 @@
> red_vmc_channel_port_class_init(RedVmcChannelPortClass *klass)
>  }
>  
>  static void spicevmc_connect(RedChannel *channel, RedClient *client,
> -    RedsStream *stream, int migration, int num_common_caps,
> -    uint32_t *common_caps, int num_caps, uint32_t *caps)
> +    RedsStream *stream, int migration,
> +    GArray *common_caps, GArray *caps)
>  {
>      RedChannelClient *rcc;
>      RedVmcChannel *vmc_channel;
> @@ -787,7 +787,7 @@ static void spicevmc_connect(RedChannel *channel,
> RedClient *client,
>      }
>  
>      rcc = red_channel_client_create(channel, client, stream, FALSE,
> -                                    num_common_caps, common_caps,
> num_caps, caps);
> +                                    common_caps, caps);
>      if (!rcc) {
>          return;
>      }


More information about the Spice-devel mailing list