[Spice-devel] [PATCH spice-server 4/4] Convert ClientCbs to channel virtual functions

Christophe Fergeau cfergeau at redhat.com
Wed Aug 30 07:06:50 UTC 2017


On Tue, Aug 29, 2017 at 05:28:09PM -0500, Jonathon Jongsma wrote:
> These client callbacks really make more sense as virtual functions of
> the channel class. We never set different callbacks for different
> objects of the same class, so there's no need to be able to register
> e.g. different callbacks for different DisplayChannels.
> 
> In the process, the signature for 'disconnect' and 'migrate' were
> changed slightly to provide a 'self' pointer to the channel as the first
> argument.

Acked-by: Christophe Fergeau <cfergeau at redhat.com>

I'd use this as an opportunity to remove the 
channel_client_connect_proc, channel_client_disconnect_proc
and channel_client_migrate_proc typedef which are only used once. The
types can be used directly in RedChannelClass definition, no need for
the typedef indirection in my opinion.

Christophe

> 
> Signed-off-by: Jonathon Jongsma <jjongsma at redhat.com>
> ---
>  server/cursor-channel.c      | 26 ++++++---------------
>  server/display-channel.c     | 18 ++++++---------
>  server/inputs-channel.c      | 11 ++++-----
>  server/main-channel-client.c |  8 -------
>  server/main-channel-client.h |  1 -
>  server/main-channel.c        | 13 +++++++----
>  server/red-channel.c         | 54 +++++++++++++++++---------------------------
>  server/red-channel.h         | 25 +++++++++-----------
>  server/smartcard.c           |  6 ++---
>  server/sound.c               | 21 ++++++++---------
>  server/spicevmc.c            |  7 +++---
>  11 files changed, 74 insertions(+), 116 deletions(-)
> 
> diff --git a/server/cursor-channel.c b/server/cursor-channel.c
> index 02a9fe3a1..d3c1dcc71 100644
> --- a/server/cursor-channel.c
> +++ b/server/cursor-channel.c
> @@ -454,12 +454,11 @@ static void red_qxl_set_cursor_peer(RedChannel *channel, RedClient *client, Reds
>                              &payload);
>  }
>  
> -static void red_qxl_disconnect_cursor_peer(RedChannelClient *rcc)
> +static void red_qxl_disconnect_cursor_peer(RedChannel *channel, RedChannelClient *rcc)
>  {
>      RedWorkerMessageCursorDisconnect payload;
>      QXLInstance *qxl;
>      Dispatcher *dispatcher;
> -    RedChannel *channel = red_channel_client_get_channel(rcc);
>  
>      if (!channel) {
>          return;
> @@ -475,12 +474,11 @@ static void red_qxl_disconnect_cursor_peer(RedChannelClient *rcc)
>                              &payload);
>  }
>  
> -static void red_qxl_cursor_migrate(RedChannelClient *rcc)
> +static void red_qxl_cursor_migrate(RedChannel *channel, RedChannelClient *rcc)
>  {
>      RedWorkerMessageCursorMigrate payload;
>      QXLInstance *qxl;
>      Dispatcher *dispatcher;
> -    RedChannel *channel = red_channel_client_get_channel(rcc);
>      uint32_t type, id;
>  
>      if (!channel) {
> @@ -497,26 +495,11 @@ static void red_qxl_cursor_migrate(RedChannelClient *rcc)
>  }
>  
>  static void
> -cursor_channel_constructed(GObject *object)
> -{
> -    RedChannel *channel = RED_CHANNEL(object);
> -    ClientCbs client_cbs = { NULL, };
> -
> -    G_OBJECT_CLASS(cursor_channel_parent_class)->constructed(object);
> -
> -    client_cbs.connect = red_qxl_set_cursor_peer;
> -    client_cbs.disconnect = red_qxl_disconnect_cursor_peer;
> -    client_cbs.migrate = red_qxl_cursor_migrate;
> -    red_channel_register_client_cbs(channel, &client_cbs, NULL);
> -}
> -
> -static void
>  cursor_channel_class_init(CursorChannelClass *klass)
>  {
>      GObjectClass *object_class = G_OBJECT_CLASS(klass);
>      RedChannelClass *channel_class = RED_CHANNEL_CLASS(klass);
>  
> -    object_class->constructed = cursor_channel_constructed;
>      object_class->finalize = cursor_channel_finalize;
>  
>      channel_class->parser = spice_get_client_channel_parser(SPICE_CHANNEL_CURSOR, NULL);
> @@ -524,6 +507,11 @@ cursor_channel_class_init(CursorChannelClass *klass)
>  
>      channel_class->on_disconnect =  cursor_channel_client_on_disconnect;
>      channel_class->send_item = cursor_channel_send_item;
> +
> +    /* client cbs */
> +    channel_class->connect = red_qxl_set_cursor_peer;
> +    channel_class->disconnect = red_qxl_disconnect_cursor_peer;
> +    channel_class->migrate = red_qxl_cursor_migrate;
>  }
>  
>  static void
> diff --git a/server/display-channel.c b/server/display-channel.c
> index cccf1dea9..a55b857d6 100644
> --- a/server/display-channel.c
> +++ b/server/display-channel.c
> @@ -2310,12 +2310,11 @@ static void red_qxl_set_display_peer(RedChannel *channel, RedClient *client,
>                              &payload);
>  }
>  
> -static void red_qxl_disconnect_display_peer(RedChannelClient *rcc)
> +static void red_qxl_disconnect_display_peer(RedChannel *channel, RedChannelClient *rcc)
>  {
>      RedWorkerMessageDisplayDisconnect payload;
>      QXLInstance *qxl;
>      Dispatcher *dispatcher;
> -    RedChannel *channel = red_channel_client_get_channel(rcc);
>  
>      if (!channel) {
>          return;
> @@ -2334,12 +2333,11 @@ static void red_qxl_disconnect_display_peer(RedChannelClient *rcc)
>                              &payload);
>  }
>  
> -static void red_qxl_display_migrate(RedChannelClient *rcc)
> +static void red_qxl_display_migrate(RedChannel *channel, RedChannelClient *rcc)
>  {
>      RedWorkerMessageDisplayMigrate payload;
>      QXLInstance *qxl;
>      Dispatcher *dispatcher;
> -    RedChannel *channel = red_channel_client_get_channel(rcc);
>      uint32_t type, id;
>  
>      if (!channel) {
> @@ -2362,7 +2360,6 @@ display_channel_constructed(GObject *object)
>  {
>      DisplayChannel *self = DISPLAY_CHANNEL(object);
>      RedChannel *channel = RED_CHANNEL(self);
> -    ClientCbs client_cbs = { NULL, };
>  
>      G_OBJECT_CLASS(display_channel_parent_class)->constructed(object);
>  
> @@ -2389,12 +2386,6 @@ display_channel_constructed(GObject *object)
>      red_channel_set_cap(channel, SPICE_DISPLAY_CAP_PREF_COMPRESSION);
>      red_channel_set_cap(channel, SPICE_DISPLAY_CAP_PREF_VIDEO_CODEC_TYPE);
>      red_channel_set_cap(channel, SPICE_DISPLAY_CAP_STREAM_REPORT);
> -
> -    client_cbs.connect = red_qxl_set_display_peer;
> -    client_cbs.disconnect = red_qxl_disconnect_display_peer;
> -    client_cbs.migrate = red_qxl_display_migrate;
> -
> -    red_channel_register_client_cbs(channel, &client_cbs, NULL);
>  }
>  
>  void display_channel_process_surface_cmd(DisplayChannel *display,
> @@ -2589,6 +2580,11 @@ display_channel_class_init(DisplayChannelClass *klass)
>      channel_class->handle_migrate_data = handle_migrate_data;
>      channel_class->handle_migrate_data_get_serial = handle_migrate_data_get_serial;
>  
> +    /* client cbs */
> +    channel_class->connect = red_qxl_set_display_peer;
> +    channel_class->disconnect = red_qxl_disconnect_display_peer;
> +    channel_class->migrate = red_qxl_display_migrate;
> +
>      g_object_class_install_property(object_class,
>                                      PROP_N_SURFACES,
>                                      g_param_spec_uint("n-surfaces",
> diff --git a/server/inputs-channel.c b/server/inputs-channel.c
> index 943c69d6c..51dec304f 100644
> --- a/server/inputs-channel.c
> +++ b/server/inputs-channel.c
> @@ -471,9 +471,9 @@ static void inputs_connect(RedChannel *channel, RedClient *client,
>      inputs_pipe_add_init(rcc);
>  }
>  
> -static void inputs_migrate(RedChannelClient *rcc)
> +static void inputs_migrate(RedChannel *self, RedChannelClient *rcc)
>  {
> -    InputsChannel *inputs = INPUTS_CHANNEL(red_channel_client_get_channel(rcc));
> +    InputsChannel *inputs = INPUTS_CHANNEL(self);
>      inputs->src_during_migrate = TRUE;
>      red_channel_client_default_migrate(rcc);
>  }
> @@ -545,16 +545,11 @@ InputsChannel* inputs_channel_new(RedsState *reds)
>  static void
>  inputs_channel_constructed(GObject *object)
>  {
> -    ClientCbs client_cbs = { NULL, };
>      InputsChannel *self = INPUTS_CHANNEL(object);
>      RedsState *reds = red_channel_get_server(RED_CHANNEL(self));
>  
>      G_OBJECT_CLASS(inputs_channel_parent_class)->constructed(object);
>  
> -    client_cbs.connect = inputs_connect;
> -    client_cbs.migrate = inputs_migrate;
> -    red_channel_register_client_cbs(RED_CHANNEL(self), &client_cbs, NULL);
> -
>      red_channel_set_cap(RED_CHANNEL(self), SPICE_INPUTS_CAP_KEY_SCANCODE);
>      reds_register_channel(reds, RED_CHANNEL(self));
>  
> @@ -598,6 +593,8 @@ inputs_channel_class_init(InputsChannelClass *klass)
>      channel_class->send_item = inputs_channel_send_item;
>      channel_class->handle_migrate_data = inputs_channel_handle_migrate_data;
>      channel_class->handle_migrate_flush_mark = inputs_channel_handle_migrate_flush_mark;
> +    channel_class->connect = inputs_connect;
> +    channel_class->migrate = inputs_migrate;
>  }
>  
>  static SpiceKbdInstance* inputs_channel_get_keyboard(InputsChannel *inputs)
> diff --git a/server/main-channel-client.c b/server/main-channel-client.c
> index 82b578c8b..4f25462c1 100644
> --- a/server/main-channel-client.c
> +++ b/server/main-channel-client.c
> @@ -646,14 +646,6 @@ uint64_t main_channel_client_get_roundtrip_ms(MainChannelClient *mcc)
>      return mcc->priv->latency / 1000;
>  }
>  
> -void main_channel_client_migrate(RedChannelClient *rcc)
> -{
> -    RedChannel *channel = red_channel_client_get_channel(rcc);
> -    reds_on_main_channel_migrate(red_channel_get_server(channel),
> -                                 MAIN_CHANNEL_CLIENT(rcc));
> -    red_channel_client_default_migrate(rcc);
> -}
> -
>  gboolean main_channel_client_connect_semi_seamless(MainChannelClient *mcc)
>  {
>      RedChannelClient *rcc = RED_CHANNEL_CLIENT(mcc);
> diff --git a/server/main-channel-client.h b/server/main-channel-client.h
> index a2e38c2fb..dbdf0243d 100644
> --- a/server/main-channel-client.h
> +++ b/server/main-channel-client.h
> @@ -74,7 +74,6 @@ void main_channel_client_push_init(MainChannelClient *mcc,
>                                     int multi_media_time,
>                                     int ram_hint);
>  void main_channel_client_push_notify(MainChannelClient *mcc, const char *msg);
> -void main_channel_client_migrate(RedChannelClient *rcc);
>  gboolean main_channel_client_connect_semi_seamless(MainChannelClient *mcc);
>  void main_channel_client_connect_seamless(MainChannelClient *mcc);
>  void main_channel_client_handle_migrate_connected(MainChannelClient *mcc,
> diff --git a/server/main-channel.c b/server/main-channel.c
> index 4834f79b6..ec0c538ac 100644
> --- a/server/main-channel.c
> +++ b/server/main-channel.c
> @@ -283,19 +283,22 @@ MainChannel* main_channel_new(RedsState *reds)
>                          NULL);
>  }
>  
> +static void main_channel_client_migrate(RedChannel *self, RedChannelClient *rcc)
> +{
> +    reds_on_main_channel_migrate(red_channel_get_server(self),
> +                                 MAIN_CHANNEL_CLIENT(rcc));
> +    red_channel_client_default_migrate(rcc);
> +}
> +
>  static void
>  main_channel_constructed(GObject *object)
>  {
>      MainChannel *self = MAIN_CHANNEL(object);
> -    ClientCbs client_cbs = { NULL, };
>  
>      G_OBJECT_CLASS(main_channel_parent_class)->constructed(object);
>  
>      red_channel_set_cap(RED_CHANNEL(self), SPICE_MAIN_CAP_SEMI_SEAMLESS_MIGRATE);
>      red_channel_set_cap(RED_CHANNEL(self), SPICE_MAIN_CAP_SEAMLESS_MIGRATE);
> -
> -    client_cbs.migrate = main_channel_client_migrate;
> -    red_channel_register_client_cbs(RED_CHANNEL(self), &client_cbs, NULL);
>  }
>  
>  static void
> @@ -319,6 +322,8 @@ main_channel_class_init(MainChannelClass *klass)
>      channel_class->send_item = main_channel_client_send_item;
>      channel_class->handle_migrate_flush_mark = main_channel_handle_migrate_flush_mark;
>      channel_class->handle_migrate_data = main_channel_handle_migrate_data;
> +    /* client cbs */
> +    channel_class->migrate = main_channel_client_migrate;
>  }
>  
>  static int main_channel_connect_semi_seamless(MainChannel *main_channel)
> diff --git a/server/red-channel.c b/server/red-channel.c
> index 9ff3474a7..b8e2e886d 100644
> --- a/server/red-channel.c
> +++ b/server/red-channel.c
> @@ -91,9 +91,6 @@ struct RedChannelPrivate
>      RedChannelCapabilities local_caps;
>      uint32_t migration_flags;
>  
> -    void *data;
> -
> -    ClientCbs client_cbs;
>      // TODO: when different channel_clients are in different threads
>      // from Channel -> need to protect!
>      pthread_t thread_id;
> @@ -201,19 +198,19 @@ red_channel_constructed(GObject *object)
>      spice_assert(klass->on_disconnect);
>      spice_assert(klass->handle_migrate_data ||
>                   !(self->priv->migration_flags & SPICE_MIGRATE_NEED_DATA_TRANSFER));
> +    spice_assert(klass->connect || self->priv->type == SPICE_CHANNEL_MAIN);
>  }
>  
> -static void red_channel_client_default_connect(RedChannel *channel, RedClient *client,
> -                                               RedsStream *stream,
> -                                               int migration,
> -                                               RedChannelCapabilities *caps)
> +static void red_channel_default_client_disconnect(RedChannel *self G_GNUC_UNUSED,
> +                                                  RedChannelClient *rcc)
>  {
> -    spice_error("not implemented");
> +    red_channel_client_disconnect(rcc);
>  }
>  
> -static void red_channel_client_default_disconnect(RedChannelClient *base)
> +static void red_channel_default_client_migrate(RedChannel *self G_GNUC_UNUSED,
> +                                               RedChannelClient *rcc)
>  {
> -    red_channel_client_disconnect(base);
> +    red_channel_client_default_migrate(rcc);
>  }
>  
>  static void
> @@ -229,6 +226,11 @@ red_channel_class_init(RedChannelClass *klass)
>      object_class->finalize = red_channel_finalize;
>      object_class->constructed = red_channel_constructed;
>  
> +    /* client cbs */
> +    klass->disconnect = red_channel_default_client_disconnect;
> +    klass->migrate = red_channel_default_client_migrate;
> +    /* 'connect' must be implemented by sub-classes */
> +
>      spec = g_param_spec_pointer("spice-server",
>                                  "spice-server",
>                                  "The spice server associated with this channel",
> @@ -296,10 +298,6 @@ red_channel_init(RedChannel *self)
>  
>      red_channel_set_common_cap(self, SPICE_COMMON_CAP_MINI_HEADER);
>      self->priv->thread_id = pthread_self();
> -
> -    self->priv->client_cbs.connect = red_channel_client_default_connect;
> -    self->priv->client_cbs.disconnect = red_channel_client_default_disconnect;
> -    self->priv->client_cbs.migrate = red_channel_client_default_migrate;
>  }
>  
>  
> @@ -356,22 +354,6 @@ const RedStatNode *red_channel_get_stat_node(RedChannel *channel)
>      return &channel->priv->stat;
>  }
>  
> -void red_channel_register_client_cbs(RedChannel *channel, const ClientCbs *client_cbs,
> -                                     gpointer cbs_data)
> -{
> -    spice_assert(client_cbs->connect || channel->priv->type == SPICE_CHANNEL_MAIN);
> -    channel->priv->client_cbs.connect = client_cbs->connect;
> -
> -    if (client_cbs->disconnect) {
> -        channel->priv->client_cbs.disconnect = client_cbs->disconnect;
> -    }
> -
> -    if (client_cbs->migrate) {
> -        channel->priv->client_cbs.migrate = client_cbs->migrate;
> -    }
> -    channel->priv->data = cbs_data;
> -}
> -
>  static void add_capability(uint32_t **caps, int *num_caps, uint32_t cap)
>  {
>      int nbefore, n;
> @@ -489,7 +471,9 @@ void red_channel_connect(RedChannel *channel, RedClient *client,
>                           RedsStream *stream, int migration,
>                           RedChannelCapabilities *caps)
>  {
> -    channel->priv->client_cbs.connect(channel, client, stream, migration, caps);
> +    RedChannelClass *klass = RED_CHANNEL_GET_CLASS(channel);
> +    g_return_if_fail(klass->connect);
> +    klass->connect(channel, client, stream, migration, caps);
>  }
>  
>  void red_channel_apply_clients(RedChannel *channel, channel_client_callback cb)
> @@ -719,10 +703,14 @@ const RedChannelCapabilities* red_channel_get_local_capabilities(RedChannel *sel
>  
>  void red_channel_migrate_client(RedChannel *channel, RedChannelClient *rcc)
>  {
> -    channel->priv->client_cbs.migrate(rcc);
> +    RedChannelClass *klass = RED_CHANNEL_GET_CLASS(channel);
> +    g_return_if_fail(klass->migrate);
> +    klass->migrate(channel, rcc);
>  }
>  
>  void red_channel_disconnect_client(RedChannel *channel, RedChannelClient *rcc)
>  {
> -    channel->priv->client_cbs.disconnect(rcc);
> +    RedChannelClass *klass = RED_CHANNEL_GET_CLASS(channel);
> +    g_return_if_fail(klass->disconnect);
> +    klass->disconnect(channel, rcc);
>  }
> diff --git a/server/red-channel.h b/server/red-channel.h
> index e65eea1eb..c7817fa5e 100644
> --- a/server/red-channel.h
> +++ b/server/red-channel.h
> @@ -56,22 +56,12 @@ typedef uint64_t (*channel_handle_migrate_data_get_serial_proc)(RedChannelClient
>                                              uint32_t size, void *message);
>  
>  
> -typedef void (*channel_client_connect_proc)(RedChannel *channel, RedClient *client, RedsStream *stream,
> +typedef void (*channel_client_connect_proc)(RedChannel *self, RedClient *client, RedsStream *stream,
>                                              int migration, RedChannelCapabilities *caps);
> -typedef void (*channel_client_disconnect_proc)(RedChannelClient *base);
> -typedef void (*channel_client_migrate_proc)(RedChannelClient *base);
> +typedef void (*channel_client_disconnect_proc)(RedChannel *self, RedChannelClient *base);
> +typedef void (*channel_client_migrate_proc)(RedChannel *self, RedChannelClient *base);
>  
>  
> -/*
> - * callbacks that are triggered from client events.
> - * They should be called from the thread that handles the RedClient
> - */
> -typedef struct {
> -    channel_client_connect_proc connect;
> -    channel_client_disconnect_proc disconnect;
> -    channel_client_migrate_proc migrate;
> -} ClientCbs;
> -
>  static inline gboolean test_capability(const uint32_t *caps, int num_caps, uint32_t cap)
>  {
>      return VD_AGENT_HAS_CAPABILITY(caps, num_caps, cap);
> @@ -120,6 +110,14 @@ struct RedChannelClass
>      channel_handle_migrate_flush_mark_proc handle_migrate_flush_mark;
>      channel_handle_migrate_data_proc handle_migrate_data;
>      channel_handle_migrate_data_get_serial_proc handle_migrate_data_get_serial;
> +
> +    /*
> +     * callbacks that are triggered from client events.
> +     * They should be called from the thread that handles the RedClient
> +     */
> +    channel_client_connect_proc connect;
> +    channel_client_disconnect_proc disconnect;
> +    channel_client_migrate_proc migrate;
>  };
>  
>  #define FOREACH_CLIENT(_channel, _data) \
> @@ -135,7 +133,6 @@ void red_channel_remove_client(RedChannel *channel, RedChannelClient *rcc);
>  
>  void red_channel_init_stat_node(RedChannel *channel, const RedStatNode *parent, const char *name);
>  
> -void red_channel_register_client_cbs(RedChannel *channel, const ClientCbs *client_cbs, gpointer cbs_data);
>  // caps are freed when the channel is destroyed
>  void red_channel_set_common_cap(RedChannel *channel, uint32_t cap);
>  void red_channel_set_cap(RedChannel *channel, uint32_t cap);
> diff --git a/server/smartcard.c b/server/smartcard.c
> index ac2fc1e19..e420c8d1f 100644
> --- a/server/smartcard.c
> +++ b/server/smartcard.c
> @@ -554,13 +554,9 @@ red_smartcard_channel_constructed(GObject *object)
>  {
>      RedSmartcardChannel *self = RED_SMARTCARD_CHANNEL(object);
>      RedsState *reds = red_channel_get_server(RED_CHANNEL(self));
> -    ClientCbs client_cbs = { NULL, };
>  
>      G_OBJECT_CLASS(red_smartcard_channel_parent_class)->constructed(object);
>  
> -    client_cbs.connect = smartcard_connect_client;
> -    red_channel_register_client_cbs(RED_CHANNEL(self), &client_cbs, NULL);
> -
>      reds_register_channel(reds, RED_CHANNEL(self));
>  }
>  
> @@ -579,6 +575,8 @@ red_smartcard_channel_class_init(RedSmartcardChannelClass *klass)
>      channel_class->handle_migrate_flush_mark = smartcard_channel_client_handle_migrate_flush_mark;
>      channel_class->handle_migrate_data = smartcard_channel_client_handle_migrate_data;
>  
> +    /* client cbs */
> +    channel_class->connect = smartcard_connect_client;
>  }
>  
>  static void smartcard_init(RedsState *reds)
> diff --git a/server/sound.c b/server/sound.c
> index 54b897139..4810ac2f5 100644
> --- a/server/sound.c
> +++ b/server/sound.c
> @@ -1117,7 +1117,8 @@ static void snd_set_playback_peer(RedChannel *red_channel, RedClient *client, Re
>                   TYPE_PLAYBACK_CHANNEL_CLIENT);
>  }
>  
> -static void snd_migrate_channel_client(RedChannelClient *rcc)
> +static void snd_migrate_channel_client(RedChannel *channel G_GNUC_UNUSED,
> +                                       RedChannelClient *rcc)
>  {
>      snd_set_command(SND_CHANNEL_CLIENT(rcc), SND_MIGRATE_MASK);
>      snd_send(SND_CHANNEL_CLIENT(rcc));
> @@ -1331,16 +1332,11 @@ playback_channel_init(PlaybackChannel *self)
>  static void
>  playback_channel_constructed(GObject *object)
>  {
> -    ClientCbs client_cbs = { NULL, };
>      SndChannel *self = SND_CHANNEL(object);
>      RedsState *reds = red_channel_get_server(RED_CHANNEL(self));
>  
>      G_OBJECT_CLASS(playback_channel_parent_class)->constructed(object);
>  
> -    client_cbs.connect = snd_set_playback_peer;
> -    client_cbs.migrate = snd_migrate_channel_client;
> -    red_channel_register_client_cbs(RED_CHANNEL(self), &client_cbs, self);
> -
>      if (snd_codec_is_capable(SPICE_AUDIO_DATA_MODE_CELT_0_5_1, SND_CODEC_ANY_FREQUENCY)) {
>          red_channel_set_cap(RED_CHANNEL(self), SPICE_PLAYBACK_CAP_CELT_0_5_1);
>      }
> @@ -1361,6 +1357,10 @@ playback_channel_class_init(PlaybackChannelClass *klass)
>      channel_class->parser = spice_get_client_channel_parser(SPICE_CHANNEL_PLAYBACK, NULL);
>      channel_class->handle_message = red_channel_client_handle_message;
>      channel_class->send_item = playback_channel_send_item;
> +
> +    /* client cbs */
> +    channel_class->connect = snd_set_playback_peer;
> +    channel_class->migrate = snd_migrate_channel_client;
>  }
>  
>  void snd_attach_playback(RedsState *reds, SpicePlaybackInstance *sin)
> @@ -1381,16 +1381,11 @@ record_channel_init(RecordChannel *self)
>  static void
>  record_channel_constructed(GObject *object)
>  {
> -    ClientCbs client_cbs = { NULL, };
>      SndChannel *self = SND_CHANNEL(object);
>      RedsState *reds = red_channel_get_server(RED_CHANNEL(self));
>  
>      G_OBJECT_CLASS(record_channel_parent_class)->constructed(object);
>  
> -    client_cbs.connect = snd_set_record_peer;
> -    client_cbs.migrate = snd_migrate_channel_client;
> -    red_channel_register_client_cbs(RED_CHANNEL(self), &client_cbs, self);
> -
>      if (snd_codec_is_capable(SPICE_AUDIO_DATA_MODE_CELT_0_5_1, SND_CODEC_ANY_FREQUENCY)) {
>          red_channel_set_cap(RED_CHANNEL(self), SPICE_RECORD_CAP_CELT_0_5_1);
>      }
> @@ -1411,6 +1406,10 @@ record_channel_class_init(RecordChannelClass *klass)
>      channel_class->parser = spice_get_client_channel_parser(SPICE_CHANNEL_RECORD, NULL);
>      channel_class->handle_message = record_channel_handle_message;
>      channel_class->send_item = record_channel_send_item;
> +
> +    /* client cbs */
> +    channel_class->connect = snd_set_record_peer;
> +    channel_class->migrate = snd_migrate_channel_client;
>  }
>  
>  void snd_attach_record(RedsState *reds, SpiceRecordInstance *sin)
> diff --git a/server/spicevmc.c b/server/spicevmc.c
> index 9305c9b4b..2f1a5b533 100644
> --- a/server/spicevmc.c
> +++ b/server/spicevmc.c
> @@ -225,14 +225,10 @@ static void
>  red_vmc_channel_constructed(GObject *object)
>  {
>      RedVmcChannel *self = RED_VMC_CHANNEL(object);
> -    ClientCbs client_cbs = { NULL, };
>      RedsState *reds = red_channel_get_server(RED_CHANNEL(self));
>  
>      G_OBJECT_CLASS(red_vmc_channel_parent_class)->constructed(object);
>  
> -    client_cbs.connect = spicevmc_connect;
> -    red_channel_register_client_cbs(RED_CHANNEL(self), &client_cbs, NULL);
> -
>      red_channel_init_stat_node(RED_CHANNEL(self), NULL, "spicevmc");
>      const RedStatNode *stat = red_channel_get_stat_node(RED_CHANNEL(self));
>      stat_init_counter(&self->in_data, reds, stat, "in_data", TRUE);
> @@ -767,6 +763,9 @@ red_vmc_channel_class_init(RedVmcChannelClass *klass)
>      channel_class->send_item = spicevmc_red_channel_send_item;
>      channel_class->handle_migrate_flush_mark = spicevmc_channel_client_handle_migrate_flush_mark;
>      channel_class->handle_migrate_data = spicevmc_channel_client_handle_migrate_data;
> +
> +    /* client cbs */
> +    channel_class->connect = spicevmc_connect;
>  }
>  
>  static void
> -- 
> 2.13.3
> 
> _______________________________________________
> Spice-devel mailing list
> Spice-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/spice-devel


More information about the Spice-devel mailing list