[Spice-devel] [PATCH 1/5] Add red_channel_client_get_channel()

Jonathon Jongsma jjongsma at redhat.com
Tue Aug 30 15:25:52 UTC 2016


Don't poke into the structure to get the channel

This prepares for encapsulating RedChannelClient a bit more and
separating it into its own source file.
---
 server/cursor-channel.c        |  4 ++--
 server/dcc-send.c              | 10 +++++----
 server/dcc.c                   |  4 ++--
 server/dcc.h                   |  2 +-
 server/display-channel.c       |  3 +--
 server/inputs-channel-client.c |  2 +-
 server/inputs-channel.c        | 14 ++++++-------
 server/main-channel-client.c   | 47 ++++++++++++++++++++++++++----------------
 server/main-channel.c          | 29 +++++++++++++++-----------
 server/red-channel.c           | 17 ++++++++++++---
 server/red-channel.h           |  1 +
 server/red-qxl.c               | 24 ++++++++++++---------
 server/red-worker.c            |  3 ++-
 server/sound.c                 | 27 ++++++++++++++----------
 server/spicevmc.c              |  6 ++++--
 server/stream.c                |  6 ++++--
 16 files changed, 121 insertions(+), 78 deletions(-)

diff --git a/server/cursor-channel.c b/server/cursor-channel.c
index dac929a..1e753c7 100644
--- a/server/cursor-channel.c
+++ b/server/cursor-channel.c
@@ -235,7 +235,7 @@ static void red_marshall_cursor_init(CursorChannelClient *ccc, SpiceMarshaller *
     AddBufInfo info;
 
     spice_assert(rcc);
-    cursor_channel = SPICE_CONTAINEROF(rcc->channel, CursorChannel, common.base);
+    cursor_channel = (CursorChannel*)red_channel_client_get_channel(rcc);
 
     red_channel_client_init_send_data(rcc, SPICE_MSG_CURSOR_INIT, NULL);
     msg.visible = cursor_channel->cursor_visible;
@@ -253,7 +253,7 @@ static void cursor_marshall(CursorChannelClient *ccc,
                             RedCursorPipeItem *cursor_pipe_item)
 {
     RedChannelClient *rcc = RED_CHANNEL_CLIENT(ccc);
-    CursorChannel *cursor_channel = SPICE_CONTAINEROF(rcc->channel, CursorChannel, common.base);
+    CursorChannel *cursor_channel = (CursorChannel*)red_channel_client_get_channel(rcc);
     CursorItem *item = cursor_pipe_item->cursor_item;
     RedPipeItem *pipe_item = &cursor_pipe_item->base;
     RedCursorCmd *cmd;
diff --git a/server/dcc-send.c b/server/dcc-send.c
index 406907b..0a41020 100644
--- a/server/dcc-send.c
+++ b/server/dcc-send.c
@@ -195,8 +195,8 @@ static void red_display_add_image_to_pixmap_cache(RedChannelClient *rcc,
                                                   SpiceImage *image, SpiceImage *io_image,
                                                   int is_lossy)
 {
-    DisplayChannel *display_channel = SPICE_CONTAINEROF(rcc->channel, DisplayChannel, common.base);
     DisplayChannelClient *dcc = RCC_TO_DCC(rcc);
+    DisplayChannel *display_channel = DCC_TO_DC(dcc);
 
     if ((image->descriptor.flags & SPICE_IMAGE_FLAGS_CACHE_ME)) {
         spice_assert(image->descriptor.width * image->descriptor.height > 0);
@@ -1834,7 +1834,7 @@ static void display_channel_marshall_migrate_data(RedChannelClient *rcc,
     DisplayChannelClient *dcc = RCC_TO_DCC(rcc);
     SpiceMigrateDataDisplay display_data = {0,};
 
-    display_channel = SPICE_CONTAINEROF(rcc->channel, DisplayChannel, common.base);
+    display_channel = DCC_TO_DC(dcc);
 
     red_channel_client_init_send_data(rcc, SPICE_MSG_MIGRATE_DATA, NULL);
     spice_marshaller_add_uint32(base_marshaller, SPICE_MIGRATE_DATA_DISPLAY_MAGIC);
@@ -2137,7 +2137,8 @@ static void marshall_qxl_drawable(RedChannelClient *rcc,
     spice_return_if_fail(rcc);
 
     Drawable *item = dpi->drawable;
-    DisplayChannel *display = SPICE_CONTAINEROF(rcc->channel, DisplayChannel, common.base);
+    DisplayChannel *display = SPICE_CONTAINEROF(red_channel_client_get_channel(rcc),
+                                                DisplayChannel, common.base);
 
     spice_return_if_fail(display);
     /* allow sized frames to be streamed, even if they where replaced by another frame, since
@@ -2227,11 +2228,12 @@ static void marshall_upgrade(RedChannelClient *rcc, SpiceMarshaller *m,
                              RedUpgradeItem *item)
 {
     DisplayChannelClient *dcc = RCC_TO_DCC(rcc);
+    RedChannel *channel = red_channel_client_get_channel(rcc);
     RedDrawable *red_drawable;
     SpiceMsgDisplayDrawCopy copy;
     SpiceMarshaller *src_bitmap_out, *mask_bitmap_out;
 
-    spice_assert(rcc && rcc->channel && item && item->drawable);
+    spice_assert(rcc && channel && item && item->drawable);
     red_channel_client_init_send_data(rcc, SPICE_MSG_DISPLAY_DRAW_COPY, &item->base);
 
     red_drawable = item->drawable->red_drawable;
diff --git a/server/dcc.c b/server/dcc.c
index d387e8b..9c3ab64 100644
--- a/server/dcc.c
+++ b/server/dcc.c
@@ -157,7 +157,7 @@ void dcc_create_surface(DisplayChannelClient *dcc, int surface_id)
         return;
     }
     surface = &display->surfaces[surface_id];
-    create = red_surface_create_item_new(RED_CHANNEL_CLIENT(dcc)->channel,
+    create = red_surface_create_item_new(RED_CHANNEL(display),
                                          surface_id, surface->context.width,
                                          surface->context.height,
                                          surface->context.format, flags);
@@ -549,7 +549,7 @@ void dcc_push_monitors_config(DisplayChannelClient *dcc)
         return;
     }
 
-    mci = red_monitors_config_item_new(dcc->base.channel,
+    mci = red_monitors_config_item_new(red_channel_client_get_channel(&dcc->base),
                                        monitors_config_ref(dc->monitors_config));
     red_channel_client_pipe_add(&dcc->base, &mci->pipe_item);
     red_channel_client_push(&dcc->base);
diff --git a/server/dcc.h b/server/dcc.h
index 672fb2f..0659ce7 100644
--- a/server/dcc.h
+++ b/server/dcc.h
@@ -59,7 +59,7 @@ typedef struct FreeList {
 
 typedef struct DisplayChannelClient DisplayChannelClient;
 
-#define DCC_TO_DC(dcc) ((DisplayChannel*)((RedChannelClient*)dcc)->channel)
+#define DCC_TO_DC(dcc) ((DisplayChannel*)red_channel_client_get_channel((RedChannelClient*)dcc))
 #define RCC_TO_DCC(rcc) ((DisplayChannelClient*)rcc)
 
 typedef struct RedSurfaceCreateItem {
diff --git a/server/display-channel.c b/server/display-channel.c
index 4f52b79..71acfd0 100644
--- a/server/display-channel.c
+++ b/server/display-channel.c
@@ -1858,8 +1858,7 @@ static void on_disconnect(RedChannelClient *rcc)
 
 static int handle_migrate_flush_mark(RedChannelClient *rcc)
 {
-    DisplayChannel *display_channel = SPICE_CONTAINEROF(rcc->channel, DisplayChannel, common.base);
-    RedChannel *channel = RED_CHANNEL(display_channel);
+    RedChannel *channel = red_channel_client_get_channel(rcc);
 
     red_channel_pipes_add_type(channel, RED_PIPE_ITEM_TYPE_MIGRATE_DATA);
     return TRUE;
diff --git a/server/inputs-channel-client.c b/server/inputs-channel-client.c
index 2f8acec..bdbcf5c 100644
--- a/server/inputs-channel-client.c
+++ b/server/inputs-channel-client.c
@@ -75,7 +75,7 @@ void inputs_channel_client_handle_migrate_data(InputsChannelClient *icc,
 
 void inputs_channel_client_on_mouse_motion(InputsChannelClient *icc)
 {
-    InputsChannel *inputs_channel = (InputsChannel *)icc->base.channel;
+    InputsChannel *inputs_channel = (InputsChannel *)red_channel_client_get_channel(&icc->base);
 
     if (++icc->motion_count % SPICE_INPUT_MOTION_ACK_BUNCH == 0 &&
         !inputs_channel_is_src_during_migrate(inputs_channel)) {
diff --git a/server/inputs-channel.c b/server/inputs-channel.c
index 69d0391..c28273a 100644
--- a/server/inputs-channel.c
+++ b/server/inputs-channel.c
@@ -155,7 +155,7 @@ static uint8_t *inputs_channel_alloc_msg_rcv_buf(RedChannelClient *rcc,
                                                  uint16_t type,
                                                  uint32_t size)
 {
-    InputsChannel *inputs_channel = SPICE_CONTAINEROF(rcc->channel, InputsChannel, base);
+    InputsChannel *inputs_channel = (InputsChannel*)red_channel_client_get_channel(rcc);
 
     if (size > RECEIVE_BUF_SIZE) {
         spice_printerr("error: too large incoming message");
@@ -263,7 +263,7 @@ static void inputs_channel_send_item(RedChannelClient *rcc, RedPipeItem *base)
             red_channel_client_init_send_data(rcc, SPICE_MSG_INPUTS_MOUSE_MOTION_ACK, base);
             break;
         case RED_PIPE_ITEM_MIGRATE_DATA:
-            ((InputsChannel*)rcc->channel)->src_during_migrate = FALSE;
+            ((InputsChannel*)red_channel_client_get_channel(rcc))->src_during_migrate = FALSE;
             inputs_channel_client_send_migrate_data(rcc, m, base);
             break;
         default:
@@ -276,7 +276,7 @@ static void inputs_channel_send_item(RedChannelClient *rcc, RedPipeItem *base)
 static int inputs_channel_handle_parsed(RedChannelClient *rcc, uint32_t size, uint16_t type,
                                         void *message)
 {
-    InputsChannel *inputs_channel = (InputsChannel *)rcc->channel;
+    InputsChannel *inputs_channel = (InputsChannel *)red_channel_client_get_channel(rcc);
     InputsChannelClient *icc = (InputsChannelClient *)rcc;
     uint32_t i;
     RedsState *reds = red_channel_get_server(&inputs_channel->base);
@@ -462,13 +462,13 @@ static void inputs_channel_on_disconnect(RedChannelClient *rcc)
     if (!rcc) {
         return;
     }
-    inputs_release_keys(SPICE_CONTAINEROF(rcc->channel, InputsChannel, base));
+    inputs_release_keys((InputsChannel*)red_channel_client_get_channel(rcc));
 }
 
 static void inputs_pipe_add_init(RedChannelClient *rcc)
 {
     RedInputsInitPipeItem *item = spice_malloc(sizeof(RedInputsInitPipeItem));
-    InputsChannel *inputs = SPICE_CONTAINEROF(rcc->channel, InputsChannel, base);
+    InputsChannel *inputs = (InputsChannel*)red_channel_client_get_channel(rcc);
 
     red_pipe_item_init(&item->base, RED_PIPE_ITEM_INPUTS_INIT);
     item->modifiers = kbd_get_leds(inputs_channel_get_keyboard(inputs));
@@ -515,7 +515,7 @@ static void inputs_connect(RedChannel *channel, RedClient *client,
 
 static void inputs_migrate(RedChannelClient *rcc)
 {
-    InputsChannel *inputs = SPICE_CONTAINEROF(rcc->channel, InputsChannel, base);
+    InputsChannel *inputs = (InputsChannel*)red_channel_client_get_channel(rcc);
     inputs->src_during_migrate = TRUE;
     red_channel_client_default_migrate(rcc);
 }
@@ -552,7 +552,7 @@ static int inputs_channel_handle_migrate_data(RedChannelClient *rcc,
                                               void *message)
 {
     InputsChannelClient *icc = (InputsChannelClient*)rcc;
-    InputsChannel *inputs = SPICE_CONTAINEROF(rcc->channel, InputsChannel, base);
+    InputsChannel *inputs = (InputsChannel*)red_channel_client_get_channel(rcc);
     SpiceMigrateDataHeader *header;
     SpiceMigrateDataInputs *mig_data;
 
diff --git a/server/main-channel-client.c b/server/main-channel-client.c
index acf1bd4..7a96a57 100644
--- a/server/main-channel-client.c
+++ b/server/main-channel-client.c
@@ -337,14 +337,15 @@ void main_channel_client_handle_migrate_connected(MainChannelClient *mcc,
 {
     spice_printerr("client %p connected: %d seamless %d", mcc->base.client, success, seamless);
     if (mcc->mig_wait_connect) {
-        MainChannel *main_channel = SPICE_CONTAINEROF(mcc->base.channel, MainChannel, base);
+        RedChannel *channel = red_channel_client_get_channel(&mcc->base);
+        MainChannel *main_channel = SPICE_CONTAINEROF(channel, MainChannel, base);
 
         mcc->mig_wait_connect = FALSE;
         mcc->mig_connect_ok = success;
         spice_assert(main_channel->num_clients_mig_wait);
         spice_assert(!seamless || main_channel->num_clients_mig_wait == 1);
         if (!--main_channel->num_clients_mig_wait) {
-            reds_on_main_migrate_connected(mcc->base.channel->reds, seamless && success);
+            reds_on_main_migrate_connected(channel->reds, seamless && success);
         }
     } else {
         if (success) {
@@ -357,7 +358,8 @@ void main_channel_client_handle_migrate_connected(MainChannelClient *mcc,
 void main_channel_client_handle_migrate_dst_do_seamless(MainChannelClient *mcc,
                                                         uint32_t src_version)
 {
-    if (reds_on_migrate_dst_set_seamless(mcc->base.channel->reds, mcc, src_version)) {
+    RedChannel *channel = red_channel_client_get_channel(&mcc->base);
+    if (reds_on_migrate_dst_set_seamless(channel->reds, mcc, src_version)) {
         mcc->seamless_mig_dst = TRUE;
         red_channel_client_pipe_add_empty_msg(&mcc->base,
                                              SPICE_MSG_MAIN_MIGRATE_DST_SEAMLESS_ACK);
@@ -424,7 +426,7 @@ void main_channel_client_handle_pong(MainChannelClient *mcc, SpiceMsgPing *ping,
         red_channel_client_handle_message(rcc, size, SPICE_MSGC_PONG, ping);
     }
 #ifdef RED_STATISTICS
-    stat_update_value(rcc->channel->reds, roundtrip);
+    stat_update_value(red_channel_client_get_channel(rcc)->reds, roundtrip);
 #endif
 }
 
@@ -457,7 +459,8 @@ void main_channel_client_migrate_dst_complete(MainChannelClient *mcc)
 {
     if (mcc->mig_wait_prev_complete) {
         if (mcc->mig_wait_prev_try_seamless) {
-            spice_assert(g_list_length(mcc->base.channel->clients) == 1);
+            RedChannel *channel = red_channel_client_get_channel(&mcc->base);
+            spice_assert(g_list_length(channel->clients) == 1);
             red_channel_client_pipe_add_type(&mcc->base,
                                              RED_PIPE_ITEM_TYPE_MAIN_MIGRATE_BEGIN_SEAMLESS);
         } else {
@@ -499,6 +502,7 @@ gboolean main_channel_client_migrate_src_complete(MainChannelClient *mcc,
 static void do_ping_client(MainChannelClient *mcc,
     const char *opt, int has_interval, int interval)
 {
+    RedChannel *channel = red_channel_client_get_channel(&mcc->base);
     spice_printerr("");
     if (!opt) {
         main_channel_client_push_ping(mcc, 0);
@@ -506,9 +510,9 @@ static void do_ping_client(MainChannelClient *mcc,
         if (has_interval && interval > 0) {
             mcc->ping_interval = interval * MSEC_PER_SEC;
         }
-        reds_core_timer_start(mcc->base.channel->reds, mcc->ping_timer, mcc->ping_interval);
+        reds_core_timer_start(channel->reds, mcc->ping_timer, mcc->ping_interval);
     } else if (!strcmp(opt, "off")) {
-        reds_core_timer_cancel(mcc->base.channel->reds, mcc->ping_timer);
+        reds_core_timer_cancel(channel->reds, mcc->ping_timer);
     } else {
         return;
     }
@@ -517,14 +521,15 @@ static void do_ping_client(MainChannelClient *mcc,
 static void ping_timer_cb(void *opaque)
 {
     MainChannelClient *mcc = opaque;
+    RedChannel *channel = red_channel_client_get_channel(&mcc->base);
 
     if (!red_channel_client_is_connected(&mcc->base)) {
         spice_printerr("not connected to peer, ping off");
-        reds_core_timer_cancel(mcc->base.channel->reds, mcc->ping_timer);
+        reds_core_timer_cancel(channel->reds, mcc->ping_timer);
         return;
     }
     do_ping_client(mcc, NULL, 0, 0);
-    reds_core_timer_start(mcc->base.channel->reds, mcc->ping_timer, mcc->ping_interval);
+    reds_core_timer_start(channel->reds, mcc->ping_timer, mcc->ping_interval);
 }
 #endif /* RED_STATISTICS */
 
@@ -572,14 +577,15 @@ uint64_t main_channel_client_get_roundtrip_ms(MainChannelClient *mcc)
 
 void main_channel_client_migrate(RedChannelClient *rcc)
 {
-    reds_on_main_channel_migrate(rcc->channel->reds, SPICE_CONTAINEROF(rcc, MainChannelClient, base));
+    RedChannel *channel = red_channel_client_get_channel(rcc);
+    reds_on_main_channel_migrate(channel->reds, SPICE_CONTAINEROF(rcc, MainChannelClient, base));
     red_channel_client_default_migrate(rcc);
 }
 
 gboolean main_channel_client_connect_semi_seamless(MainChannelClient *mcc)
 {
     RedChannelClient *rcc = main_channel_client_get_base(mcc);
-    MainChannel* main_channel = SPICE_CONTAINEROF(rcc->channel, MainChannel, base);
+    MainChannel* main_channel = (MainChannel*)red_channel_client_get_channel(rcc);
     if (red_channel_client_test_remote_cap(rcc,
                                            SPICE_MAIN_CAP_SEMI_SEAMLESS_MIGRATE)) {
         RedClient *client = red_channel_client_get_client(rcc);
@@ -636,9 +642,10 @@ static void main_channel_marshall_channels(RedChannelClient *rcc,
                                            RedPipeItem *item)
 {
     SpiceMsgChannels* channels_info;
+    RedChannel *channel = red_channel_client_get_channel(rcc);
 
     red_channel_client_init_send_data(rcc, SPICE_MSG_MAIN_CHANNELS_LIST, item);
-    channels_info = reds_msg_channels_new(rcc->channel->reds);
+    channels_info = reds_msg_channels_new(channel->reds);
     spice_marshall_msg_main_channels_list(m, channels_info);
     free(channels_info);
 }
@@ -711,8 +718,9 @@ static void main_channel_marshall_migrate_data_item(RedChannelClient *rcc,
                                                     SpiceMarshaller *m,
                                                     RedPipeItem *item)
 {
+    RedChannel *channel = red_channel_client_get_channel(rcc);
     red_channel_client_init_send_data(rcc, SPICE_MSG_MIGRATE_DATA, item);
-    reds_marshall_migrate_data(rcc->channel->reds, m); // TODO: from reds split. ugly separation.
+    reds_marshall_migrate_data(channel->reds, m); // TODO: from reds split. ugly separation.
 }
 
 static void main_channel_marshall_init(RedChannelClient *rcc,
@@ -720,7 +728,7 @@ static void main_channel_marshall_init(RedChannelClient *rcc,
                                        RedInitPipeItem *item)
 {
     SpiceMsgMainInit init; // TODO - remove this copy, make RedInitPipeItem reuse SpiceMsgMainInit
-
+    RedChannel *channel = red_channel_client_get_channel(rcc);
 
     red_channel_client_init_send_data(rcc, SPICE_MSG_MAIN_INIT, &item->base);
     init.session_id = item->connection_id;
@@ -730,7 +738,7 @@ static void main_channel_marshall_init(RedChannelClient *rcc,
     if (item->is_client_mouse_allowed) {
         init.supported_mouse_modes |= SPICE_MOUSE_MODE_CLIENT;
     }
-    init.agent_connected = reds_has_vdagent(rcc->channel->reds);
+    init.agent_connected = reds_has_vdagent(channel->reds);
     init.agent_tokens = REDS_AGENT_WINDOW_SIZE;
     init.multi_media_time = item->multi_media_time;
     init.ram_hint = item->ram_hint;
@@ -772,11 +780,12 @@ static void main_channel_fill_migrate_dst_info(MainChannel *main_channel,
 static void main_channel_marshall_migrate_begin(SpiceMarshaller *m, RedChannelClient *rcc,
                                                 RedPipeItem *item)
 {
+    RedChannel *channel = red_channel_client_get_channel(rcc);
     SpiceMsgMainMigrationBegin migrate;
     MainChannel *main_ch;
 
     red_channel_client_init_send_data(rcc, SPICE_MSG_MAIN_MIGRATE_BEGIN, item);
-    main_ch = SPICE_CONTAINEROF(rcc->channel, MainChannel, base);
+    main_ch = SPICE_CONTAINEROF(channel, MainChannel, base);
     main_channel_fill_migrate_dst_info(main_ch, &migrate.dst_info);
     spice_marshall_msg_main_migrate_begin(m, &migrate);
 }
@@ -785,11 +794,12 @@ static void main_channel_marshall_migrate_begin_seamless(SpiceMarshaller *m,
                                                          RedChannelClient *rcc,
                                                          RedPipeItem *item)
 {
+    RedChannel *channel = red_channel_client_get_channel(rcc);
     SpiceMsgMainMigrateBeginSeamless migrate_seamless;
     MainChannel *main_ch;
 
     red_channel_client_init_send_data(rcc, SPICE_MSG_MAIN_MIGRATE_BEGIN_SEAMLESS, item);
-    main_ch = SPICE_CONTAINEROF(rcc->channel, MainChannel, base);
+    main_ch = SPICE_CONTAINEROF(channel, MainChannel, base);
     main_channel_fill_migrate_dst_info(main_ch, &migrate_seamless.dst_info);
     migrate_seamless.src_mig_version = SPICE_MIGRATION_PROTOCOL_VERSION;
     spice_marshall_msg_main_migrate_begin_seamless(m, &migrate_seamless);
@@ -809,12 +819,13 @@ static void main_channel_marshall_multi_media_time(RedChannelClient *rcc,
 static void main_channel_marshall_migrate_switch(SpiceMarshaller *m, RedChannelClient *rcc,
                                                  RedPipeItem *item)
 {
+    RedChannel *channel = red_channel_client_get_channel(rcc);
     SpiceMsgMainMigrationSwitchHost migrate;
     MainChannel *main_ch;
 
     spice_printerr("");
     red_channel_client_init_send_data(rcc, SPICE_MSG_MAIN_MIGRATE_SWITCH_HOST, item);
-    main_ch = SPICE_CONTAINEROF(rcc->channel, MainChannel, base);
+    main_ch = SPICE_CONTAINEROF(channel, MainChannel, base);
     migrate.port = main_ch->mig_target.port;
     migrate.sport = main_ch->mig_target.sport;
     migrate.host_size = strlen(main_ch->mig_target.host) + 1;
diff --git a/server/main-channel.c b/server/main-channel.c
index 42195e6..7c6c1f7 100644
--- a/server/main-channel.c
+++ b/server/main-channel.c
@@ -35,7 +35,7 @@ int main_channel_is_connected(MainChannel *main_chan)
  */
 static void main_channel_client_on_disconnect(RedChannelClient *rcc)
 {
-    RedsState *reds = red_channel_get_server(rcc->channel);
+    RedsState *reds = red_channel_get_server(red_channel_client_get_channel(rcc));
     spice_printerr("rcc=%p", rcc);
     main_dispatcher_client_disconnect(reds_get_main_dispatcher(reds), rcc->client);
 }
@@ -98,11 +98,12 @@ static void main_channel_push_migrate_data_item(MainChannel *main_chan)
 static int main_channel_handle_migrate_data(RedChannelClient *rcc,
     uint32_t size, void *message)
 {
+    RedChannel *channel = red_channel_client_get_channel(rcc);
     MainChannelClient *mcc = (MainChannelClient*)rcc;
     SpiceMigrateDataHeader *header = (SpiceMigrateDataHeader *)message;
 
     /* not supported with multi-clients */
-    spice_assert(g_list_length(rcc->channel->clients) == 1);
+    spice_assert(g_list_length(channel->clients) == 1);
 
     if (size < sizeof(SpiceMigrateDataHeader) + sizeof(SpiceMigrateDataMain)) {
         spice_printerr("bad message size %u", size);
@@ -114,7 +115,7 @@ static int main_channel_handle_migrate_data(RedChannelClient *rcc,
         spice_error("bad header");
         return FALSE;
     }
-    return reds_handle_migrate_data(rcc->channel->reds, mcc, (SpiceMigrateDataMain *)(header + 1), size);
+    return reds_handle_migrate_data(channel->reds, mcc, (SpiceMigrateDataMain *)(header + 1), size);
 }
 
 void main_channel_push_multi_media_time(MainChannel *main_chan, int time)
@@ -151,7 +152,8 @@ void main_channel_migrate_switch(MainChannel *main_chan, RedsMigSpice *mig_targe
 static int main_channel_handle_parsed(RedChannelClient *rcc, uint32_t size, uint16_t type,
                                       void *message)
 {
-    MainChannel *main_chan = SPICE_CONTAINEROF(rcc->channel, MainChannel, base);
+    RedChannel *channel = red_channel_client_get_channel(rcc);
+    MainChannel *main_chan = SPICE_CONTAINEROF(channel, MainChannel, base);
     MainChannelClient *mcc = (MainChannelClient*)rcc;
 
     switch (type) {
@@ -163,18 +165,18 @@ static int main_channel_handle_parsed(RedChannelClient *rcc, uint32_t size, uint
             return FALSE;
         }
         tokens = (SpiceMsgcMainAgentStart *)message;
-        reds_on_main_agent_start(rcc->channel->reds, mcc, tokens->num_tokens);
+        reds_on_main_agent_start(channel->reds, mcc, tokens->num_tokens);
         break;
     }
     case SPICE_MSGC_MAIN_AGENT_DATA: {
-        reds_on_main_agent_data(rcc->channel->reds, mcc, message, size);
+        reds_on_main_agent_data(channel->reds, mcc, message, size);
         break;
     }
     case SPICE_MSGC_MAIN_AGENT_TOKEN: {
         SpiceMsgcMainAgentTokens *tokens;
 
         tokens = (SpiceMsgcMainAgentTokens *)message;
-        reds_on_main_agent_tokens(rcc->channel->reds, mcc, tokens->num_tokens);
+        reds_on_main_agent_tokens(channel->reds, mcc, tokens->num_tokens);
         break;
     }
     case SPICE_MSGC_MAIN_ATTACH_CHANNELS:
@@ -198,7 +200,7 @@ static int main_channel_handle_parsed(RedChannelClient *rcc, uint32_t size, uint
             ((SpiceMsgcMainMigrateDstDoSeamless *)message)->src_version);
         break;
     case SPICE_MSGC_MAIN_MOUSE_MODE_REQUEST:
-        reds_on_main_mouse_mode_request(rcc->channel->reds, message, size);
+        reds_on_main_mouse_mode_request(channel->reds, message, size);
         break;
     case SPICE_MSGC_PONG: {
         main_channel_client_handle_pong(mcc, (SpiceMsgPing *)message, size);
@@ -219,11 +221,12 @@ static uint8_t *main_channel_alloc_msg_rcv_buf(RedChannelClient *rcc,
                                                uint16_t type,
                                                uint32_t size)
 {
-    MainChannel *main_chan = SPICE_CONTAINEROF(rcc->channel, MainChannel, base);
+    RedChannel *channel = red_channel_client_get_channel(rcc);
+    MainChannel *main_chan = SPICE_CONTAINEROF(channel, MainChannel, base);
     MainChannelClient *mcc = (MainChannelClient*)rcc;
 
     if (type == SPICE_MSGC_MAIN_AGENT_DATA) {
-        return reds_get_agent_data_buffer(rcc->channel->reds, mcc, size);
+        return reds_get_agent_data_buffer(channel->reds, mcc, size);
     } else {
         return main_chan->recv_buf;
     }
@@ -234,8 +237,9 @@ static void main_channel_release_msg_rcv_buf(RedChannelClient *rcc,
                                                uint32_t size,
                                                uint8_t *msg)
 {
+    RedChannel *channel = red_channel_client_get_channel(rcc);
     if (type == SPICE_MSGC_MAIN_AGENT_DATA) {
-        reds_release_agent_data_buffer(rcc->channel->reds, msg);
+        reds_release_agent_data_buffer(channel->reds, msg);
     }
 }
 
@@ -246,8 +250,9 @@ static int main_channel_config_socket(RedChannelClient *rcc)
 
 static int main_channel_handle_migrate_flush_mark(RedChannelClient *rcc)
 {
+    RedChannel *channel = red_channel_client_get_channel(rcc);
     spice_debug(NULL);
-    main_channel_push_migrate_data_item(SPICE_CONTAINEROF(rcc->channel,
+    main_channel_push_migrate_data_item(SPICE_CONTAINEROF(channel,
                                         MainChannel, base));
     return TRUE;
 }
diff --git a/server/red-channel.c b/server/red-channel.c
index a02c51a..615c2a3 100644
--- a/server/red-channel.c
+++ b/server/red-channel.c
@@ -2069,6 +2069,7 @@ void red_client_migrate(RedClient *client)
 {
     GList *link, *next;
     RedChannelClient *rcc;
+    RedChannel *channel;
 
     spice_printerr("migrate client with #channels %d", g_list_length(client->channels));
     if (!pthread_equal(pthread_self(), client->thread_id)) {
@@ -2081,8 +2082,9 @@ void red_client_migrate(RedClient *client)
     while (link) {
         next = link->next;
         rcc = link->data;
+        channel = red_channel_client_get_channel(rcc);
         if (red_channel_client_is_connected(rcc)) {
-            rcc->channel->client_cbs.migrate(rcc);
+            channel->client_cbs.migrate(rcc);
         }
         link = next;
     }
@@ -2103,17 +2105,19 @@ void red_client_destroy(RedClient *client)
     }
     link = client->channels;
     while (link) {
+        RedChannel *channel;
         next = link->next;
         // some channels may be in other threads, so disconnection
         // is not synchronous.
         rcc = link->data;
+        channel = red_channel_client_get_channel(rcc);
         rcc->destroying = 1;
         // some channels may be in other threads. However we currently
         // assume disconnect is synchronous (we changed the dispatcher
         // to wait for disconnection)
         // TODO: should we go back to async. For this we need to use
         // ref count for channel clients.
-        rcc->channel->client_cbs.disconnect(rcc);
+        channel->client_cbs.disconnect(rcc);
         spice_assert(ring_is_empty(&rcc->pipe));
         spice_assert(rcc->pipe_size == 0);
         spice_assert(rcc->send_data.size == 0);
@@ -2131,8 +2135,10 @@ static RedChannelClient *red_client_get_channel(RedClient *client, int type, int
     RedChannelClient *ret = NULL;
 
     for (link = client->channels; link != NULL; link = link->next) {
+        RedChannel *channel;
         rcc = link->data;
-        if (rcc->channel->type == type && rcc->channel->id == id) {
+        channel = red_channel_client_get_channel(rcc);
+        if (channel->type == type && channel->id == id) {
             ret = rcc;
             break;
         }
@@ -2437,3 +2443,8 @@ RedsState* red_channel_get_server(RedChannel *channel)
 {
     return channel->reds;
 }
+
+RedChannel* red_channel_client_get_channel(RedChannelClient *rcc)
+{
+    return rcc->channel;
+}
diff --git a/server/red-channel.h b/server/red-channel.h
index 5b38f57..039ac09 100644
--- a/server/red-channel.h
+++ b/server/red-channel.h
@@ -628,5 +628,6 @@ int red_channel_client_wait_outgoing_item(RedChannelClient *rcc,
 int red_channel_wait_all_sent(RedChannel *channel,
                               int64_t timeout);
 void red_channel_client_disconnect_if_pending_send(RedChannelClient *rcc);
+RedChannel* red_channel_client_get_channel(RedChannelClient *rcc);
 
 #endif
diff --git a/server/red-qxl.c b/server/red-qxl.c
index 2a4fa52..e517b41 100644
--- a/server/red-qxl.c
+++ b/server/red-qxl.c
@@ -102,12 +102,13 @@ static void red_qxl_disconnect_display_peer(RedChannelClient *rcc)
 {
     RedWorkerMessageDisplayDisconnect payload;
     Dispatcher *dispatcher;
+    RedChannel *channel = red_channel_client_get_channel(rcc);
 
-    if (!rcc->channel) {
+    if (!channel) {
         return;
     }
 
-    dispatcher = (Dispatcher *)rcc->channel->data;
+    dispatcher = (Dispatcher *)channel->data;
 
     spice_printerr("");
     payload.rcc = rcc;
@@ -123,11 +124,12 @@ static void red_qxl_display_migrate(RedChannelClient *rcc)
 {
     RedWorkerMessageDisplayMigrate payload;
     Dispatcher *dispatcher;
-    if (!rcc->channel) {
+    RedChannel *channel = red_channel_client_get_channel(rcc);
+    if (!channel) {
         return;
     }
-    dispatcher = (Dispatcher *)rcc->channel->data;
-    spice_printerr("channel type %u id %u", rcc->channel->type, rcc->channel->id);
+    dispatcher = (Dispatcher *)channel->data;
+    spice_printerr("channel type %u id %u", channel->type, channel->id);
     payload.rcc = rcc;
     dispatcher_send_message(dispatcher,
                             RED_WORKER_MESSAGE_DISPLAY_MIGRATE,
@@ -162,12 +164,13 @@ static void red_qxl_disconnect_cursor_peer(RedChannelClient *rcc)
 {
     RedWorkerMessageCursorDisconnect payload;
     Dispatcher *dispatcher;
+    RedChannel *channel = red_channel_client_get_channel(rcc);
 
-    if (!rcc->channel) {
+    if (!channel) {
         return;
     }
 
-    dispatcher = (Dispatcher *)rcc->channel->data;
+    dispatcher = (Dispatcher *)channel->data;
     spice_printerr("");
     payload.rcc = rcc;
 
@@ -180,12 +183,13 @@ static void red_qxl_cursor_migrate(RedChannelClient *rcc)
 {
     RedWorkerMessageCursorMigrate payload;
     Dispatcher *dispatcher;
+    RedChannel *channel = red_channel_client_get_channel(rcc);
 
-    if (!rcc->channel) {
+    if (!channel) {
         return;
     }
-    dispatcher = (Dispatcher *)rcc->channel->data;
-    spice_printerr("channel type %u id %u", rcc->channel->type, rcc->channel->id);
+    dispatcher = (Dispatcher *)channel->data;
+    spice_printerr("channel type %u id %u", channel->type, channel->id);
     payload.rcc = rcc;
     dispatcher_send_message(dispatcher,
                             RED_WORKER_MESSAGE_CURSOR_MIGRATE,
diff --git a/server/red-worker.c b/server/red-worker.c
index 34a8bff..590412b 100644
--- a/server/red-worker.c
+++ b/server/red-worker.c
@@ -101,7 +101,8 @@ static int display_is_connected(RedWorker *worker)
 
 static uint8_t *common_alloc_recv_buf(RedChannelClient *rcc, uint16_t type, uint32_t size)
 {
-    CommonGraphicsChannel *common = SPICE_CONTAINEROF(rcc->channel, CommonGraphicsChannel, base);
+    RedChannel *channel = red_channel_client_get_channel(rcc);
+    CommonGraphicsChannel *common = SPICE_CONTAINEROF(channel, CommonGraphicsChannel, base);
 
     /* SPICE_MSGC_MIGRATE_DATA is the only client message whose size is dynamic */
     if (type == SPICE_MSGC_MIGRATE_DATA) {
diff --git a/server/sound.c b/server/sound.c
index 8335101..06fab7f 100644
--- a/server/sound.c
+++ b/server/sound.c
@@ -212,14 +212,16 @@ static void snd_disconnect_channel(SndChannel *channel)
 {
     SndWorker *worker;
     RedsState *reds;
+    RedChannel *red_channel;
 
     if (!channel || !channel->stream) {
         spice_debug("not connected");
         return;
     }
+    red_channel = red_channel_client_get_channel(channel->channel_client);
     reds = snd_channel_get_server(channel);
     spice_debug("SndChannel=%p rcc=%p type=%d",
-                 channel, channel->channel_client, channel->channel_client->channel->type);
+                 channel, channel->channel_client, red_channel->type);
     worker = channel->worker;
     channel->cleanup(channel);
     red_channel_client_disconnect(worker->connection->channel_client);
@@ -992,12 +994,13 @@ error1:
 static void snd_disconnect_channel_client(RedChannelClient *rcc)
 {
     SndWorker *worker;
+    RedChannel *channel = red_channel_client_get_channel(rcc);
 
-    spice_assert(rcc->channel);
-    spice_assert(rcc->channel->data);
-    worker = (SndWorker *)rcc->channel->data;
+    spice_assert(channel);
+    spice_assert(channel->data);
+    worker = (SndWorker *)channel->data;
 
-    spice_debug("channel-type=%d", rcc->channel->type);
+    spice_debug("channel-type=%d", channel->type);
     if (worker->connection) {
         spice_assert(worker->connection->channel_client == rcc);
         snd_disconnect_channel(worker->connection);
@@ -1261,11 +1264,12 @@ static void snd_set_playback_peer(RedChannel *channel, RedClient *client, RedsSt
 static void snd_record_migrate_channel_client(RedChannelClient *rcc)
 {
     SndWorker *worker;
+    RedChannel *channel = red_channel_client_get_channel(rcc);
 
     spice_debug(NULL);
-    spice_assert(rcc->channel);
-    spice_assert(rcc->channel->data);
-    worker = (SndWorker *)rcc->channel->data;
+    spice_assert(channel);
+    spice_assert(channel->data);
+    worker = (SndWorker *)channel->data;
 
     if (worker->connection) {
         spice_assert(worker->connection->channel_client == rcc);
@@ -1490,10 +1494,11 @@ static void snd_set_record_peer(RedChannel *channel, RedClient *client, RedsStre
 static void snd_playback_migrate_channel_client(RedChannelClient *rcc)
 {
     SndWorker *worker;
+    RedChannel *channel = red_channel_client_get_channel(rcc);
 
-    spice_assert(rcc->channel);
-    spice_assert(rcc->channel->data);
-    worker = (SndWorker *)rcc->channel->data;
+    spice_assert(channel);
+    spice_assert(channel->data);
+    worker = (SndWorker *)channel->data;
     spice_debug(NULL);
 
     if (worker->connection) {
diff --git a/server/spicevmc.c b/server/spicevmc.c
index 953d193..08b3730 100644
--- a/server/spicevmc.c
+++ b/server/spicevmc.c
@@ -218,7 +218,8 @@ static void spicevmc_chardev_send_msg_to_client(RedPipeItem *msg,
 
 static SpiceVmcState *spicevmc_red_channel_client_get_state(RedChannelClient *rcc)
 {
-    return SPICE_CONTAINEROF(rcc->channel, SpiceVmcState, channel);
+    RedChannel *channel = red_channel_client_get_channel(rcc);
+    return SPICE_CONTAINEROF(channel, SpiceVmcState, channel);
 }
 
 static void spicevmc_port_send_init(RedChannelClient *rcc)
@@ -263,8 +264,9 @@ static int spicevmc_red_channel_client_config_socket(RedChannelClient *rcc)
 {
     int delay_val = 1;
     RedsStream *stream = red_channel_client_get_stream(rcc);
+    RedChannel *channel = red_channel_client_get_channel(rcc);
 
-    if (rcc->channel->type == SPICE_CHANNEL_USBREDIR) {
+    if (channel->type == SPICE_CHANNEL_USBREDIR) {
         if (setsockopt(stream->socket, IPPROTO_TCP, TCP_NODELAY,
                 &delay_val, sizeof(delay_val)) != 0) {
             if (errno != ENOTSUP && errno != ENOPROTOOPT) {
diff --git a/server/stream.c b/server/stream.c
index e070202..d302168 100644
--- a/server/stream.c
+++ b/server/stream.c
@@ -690,7 +690,9 @@ static void update_client_playback_delay(void *opaque, uint32_t delay_ms)
 {
     StreamAgent *agent = opaque;
     DisplayChannelClient *dcc = agent->dcc;
-    RedsState *reds = red_channel_get_server(RED_CHANNEL_CLIENT(dcc)->channel);
+    RedChannel *channel = red_channel_client_get_channel(RED_CHANNEL_CLIENT(dcc));
+    RedClient *client = red_channel_client_get_client(RED_CHANNEL_CLIENT(dcc));
+    RedsState *reds = red_channel_get_server(channel);
 
     dcc_update_streams_max_latency(dcc, agent);
 
@@ -700,7 +702,7 @@ static void update_client_playback_delay(void *opaque, uint32_t delay_ms)
     }
     spice_debug("resetting client latency: %u", dcc_get_max_stream_latency(agent->dcc));
     main_dispatcher_set_mm_time_latency(reds_get_main_dispatcher(reds),
-                                        RED_CHANNEL_CLIENT(agent->dcc)->client,
+                                        client,
                                         dcc_get_max_stream_latency(agent->dcc));
 }
 
-- 
2.7.4



More information about the Spice-devel mailing list