Encapsulate private data and prepare for port to GObject --- server/cursor-channel.c | 3 +- server/dcc-send.c | 22 +- server/dcc.c | 24 +- server/inputs-channel-client.c | 2 +- server/main-channel-client.c | 56 ++-- server/red-channel-client-private.h | 15 +- server/red-channel-client.c | 569 ++++++++++++++++++------------------ server/smartcard.c | 17 +- server/sound.c | 32 +- server/spicevmc.c | 4 +- 10 files changed, 397 insertions(+), 347 deletions(-) diff --git a/server/cursor-channel.c b/server/cursor-channel.c index 591d68f..97aa0bb 100644 --- a/server/cursor-channel.c +++ b/server/cursor-channel.c @@ -215,7 +215,8 @@ static void cursor_marshall(CursorChannelClient *ccc, RedCursorPipeItem *cursor_pipe_item) { RedChannelClient *rcc = RED_CHANNEL_CLIENT(ccc); - CursorChannel *cursor_channel = SPICE_CONTAINEROF(red_channel_client_get_channel(rcc), CursorChannel, common.base); + CursorChannel *cursor_channel = SPICE_CONTAINEROF(red_channel_client_get_channel(rcc), + CursorChannel, common.base); 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..da11bd3 100644 --- a/server/dcc-send.c +++ b/server/dcc-send.c @@ -188,14 +188,15 @@ static int is_brush_lossy(RedChannelClient *rcc, SpiceBrush *brush, static RedPipeItem *dcc_get_tail(DisplayChannelClient *dcc) { - return (RedPipeItem*)ring_get_tail(&RED_CHANNEL_CLIENT(dcc)->pipe); + return (RedPipeItem*)ring_get_tail(&RED_CHANNEL_CLIENT(dcc)->priv->pipe); } 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); + DisplayChannel *display_channel = SPICE_CONTAINEROF(red_channel_client_get_channel(rcc), + DisplayChannel, common.base); DisplayChannelClient *dcc = RCC_TO_DCC(rcc); if ((image->descriptor.flags & SPICE_IMAGE_FLAGS_CACHE_ME)) { @@ -441,7 +442,7 @@ static FillBitsType fill_bits(DisplayChannelClient *dcc, SpiceMarshaller *m, /* Images must be added to the cache only after they are compressed in order to prevent starvation in the client between pixmap_cache and global dictionary (in cases of multiple monitors) */ - if (reds_stream_get_family(rcc->stream) == AF_UNIX || + if (reds_stream_get_family(rcc->priv->stream) == AF_UNIX || !dcc_compress_image(dcc, &image, &simage->u.bitmap, drawable, can_lossy, &comp_send_data)) { SpicePalette *palette; @@ -620,7 +621,7 @@ static int pipe_rendered_drawables_intersect_with_areas(DisplayChannelClient *dc Ring *pipe; spice_assert(num_surfaces); - pipe = &RED_CHANNEL_CLIENT(dcc)->pipe; + pipe = &RED_CHANNEL_CLIENT(dcc)->priv->pipe; for (pipe_item = (RedPipeItem *)ring_get_head(pipe); pipe_item; @@ -712,7 +713,7 @@ static void red_pipe_replace_rendered_drawables_with_images(DisplayChannelClient resent_areas[0] = *first_area; num_resent = 1; - pipe = &RED_CHANNEL_CLIENT(dcc)->pipe; + pipe = &RED_CHANNEL_CLIENT(dcc)->priv->pipe; // going from the oldest to the newest for (pipe_item = (RedPipeItem *)ring_get_tail(pipe); @@ -1834,7 +1835,8 @@ 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 = SPICE_CONTAINEROF(red_channel_client_get_channel(rcc), + DisplayChannel, common.base); 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 +2139,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 @@ -2230,8 +2233,9 @@ static void marshall_upgrade(RedChannelClient *rcc, SpiceMarshaller *m, RedDrawable *red_drawable; SpiceMsgDisplayDrawCopy copy; SpiceMarshaller *src_bitmap_out, *mask_bitmap_out; + RedChannel *channel = red_channel_client_get_channel(rcc); - 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; @@ -2365,7 +2369,7 @@ static void begin_send_message(RedChannelClient *rcc) } free_list->wait.header.wait_count = sync_count; - if (rcc->is_mini_header) { + if (rcc->priv->is_mini_header) { send_free_list(rcc); } else { send_free_list_legacy(rcc); diff --git a/server/dcc.c b/server/dcc.c index d387e8b..fb71794 100644 --- a/server/dcc.c +++ b/server/dcc.c @@ -76,7 +76,7 @@ int dcc_clear_surface_drawables_from_pipe(DisplayChannelClient *dcc, int surface no other drawable depends on them */ rcc = RED_CHANNEL_CLIENT(dcc); - ring = &rcc->pipe; + ring = &rcc->priv->pipe; item = (RedPipeItem *) ring; while ((item = (RedPipeItem *)ring_next(ring, &item->link))) { Drawable *drawable; @@ -141,6 +141,7 @@ void dcc_create_surface(DisplayChannelClient *dcc, int surface_id) { DisplayChannel *display; RedSurface *surface; + RedChannel *channel; RedSurfaceCreateItem *create; uint32_t flags; @@ -156,8 +157,9 @@ void dcc_create_surface(DisplayChannelClient *dcc, int surface_id) dcc->surface_client_created[surface_id]) { return; } + channel = red_channel_client_get_channel(RED_CHANNEL_CLIENT(dcc)); surface = &display->surfaces[surface_id]; - create = red_surface_create_item_new(RED_CHANNEL_CLIENT(dcc)->channel, + create = red_surface_create_item_new(channel, surface_id, surface->context.width, surface->context.height, surface->context.format, flags); @@ -459,7 +461,7 @@ void dcc_start(DisplayChannelClient *dcc) dcc_create_all_streams(dcc); } - if (reds_stream_is_plain_unix(rcc->stream) && + if (reds_stream_is_plain_unix(red_channel_client_get_stream(rcc)) && red_channel_client_test_remote_cap(rcc, SPICE_DISPLAY_CAP_GL_SCANOUT)) { red_channel_client_pipe_add(rcc, dcc_gl_scanout_item_new(rcc, NULL, 0)); dcc_push_monitors_config(dcc); @@ -538,6 +540,7 @@ void dcc_push_monitors_config(DisplayChannelClient *dcc) DisplayChannel *dc = DCC_TO_DC(dcc); MonitorsConfig *monitors_config = dc->monitors_config; RedMonitorsConfigItem *mci; + RedChannel *channel; if (monitors_config == NULL) { spice_warning("monitors_config is NULL"); @@ -549,7 +552,8 @@ void dcc_push_monitors_config(DisplayChannelClient *dcc) return; } - mci = red_monitors_config_item_new(dcc->base.channel, + channel = red_channel_client_get_channel(RED_CHANNEL_CLIENT(dcc)); + mci = red_monitors_config_item_new(channel, monitors_config_ref(dc->monitors_config)); red_channel_client_pipe_add(&dcc->base, &mci->pipe_item); red_channel_client_push(&dcc->base); @@ -573,7 +577,7 @@ RedPipeItem *dcc_gl_scanout_item_new(RedChannelClient *rcc, void *data, int num) spice_return_val_if_fail(item != NULL, NULL); /* FIXME: on !unix peer, start streaming with a video codec */ - if (!reds_stream_is_plain_unix(rcc->stream) || + if (!reds_stream_is_plain_unix(red_channel_client_get_stream(rcc)) || !red_channel_client_test_remote_cap(rcc, SPICE_DISPLAY_CAP_GL_SCANOUT)) { spice_printerr("FIXME: client does not support GL scanout"); red_channel_client_disconnect(rcc); @@ -892,18 +896,19 @@ int dcc_pixmap_cache_unlocked_add(DisplayChannelClient *dcc, uint64_t id, static int dcc_handle_init(DisplayChannelClient *dcc, SpiceMsgcDisplayInit *init) { gboolean success; + RedClient *client = red_channel_client_get_client(RED_CHANNEL_CLIENT(dcc)); spice_return_val_if_fail(dcc->expect_init, FALSE); dcc->expect_init = FALSE; spice_return_val_if_fail(!dcc->pixmap_cache, FALSE); - dcc->pixmap_cache = pixmap_cache_get(RED_CHANNEL_CLIENT(dcc)->client, + dcc->pixmap_cache = pixmap_cache_get(client, init->pixmap_cache_id, init->pixmap_cache_size); spice_return_val_if_fail(dcc->pixmap_cache, FALSE); success = image_encoders_get_glz_dictionary(&dcc->encoders, - RED_CHANNEL_CLIENT(dcc)->client, + red_channel_client_get_client(RED_CHANNEL_CLIENT(dcc)), init->glz_dictionary_id, init->glz_dictionary_window_size); spice_return_val_if_fail(success, FALSE); @@ -1007,7 +1012,7 @@ static int dcc_handle_migrate_glz_dictionary(DisplayChannelClient *dcc, SpiceMigrateDataDisplay *migrate) { return image_encoders_restore_glz_dictionary(&dcc->encoders, - RED_CHANNEL_CLIENT(dcc)->client, + red_channel_client_get_client(RED_CHANNEL_CLIENT(dcc)), migrate->glz_dict_id, &migrate->glz_dict_data); } @@ -1066,6 +1071,7 @@ static int restore_surfaces_lossy(DisplayChannelClient *dcc, int dcc_handle_migrate_data(DisplayChannelClient *dcc, uint32_t size, void *message) { + RedClient *client = red_channel_client_get_client(RED_CHANNEL_CLIENT(dcc)); DisplayChannel *display = DCC_TO_DC(dcc); int surfaces_restored = FALSE; SpiceMigrateDataHeader *header = (SpiceMigrateDataHeader *)message; @@ -1083,7 +1089,7 @@ int dcc_handle_migrate_data(DisplayChannelClient *dcc, uint32_t size, void *mess * channel client that froze the cache on the src size receives the migrate * data and unfreezes the cache by setting its size > 0 and by triggering * pixmap_cache_reset */ - dcc->pixmap_cache = pixmap_cache_get(RED_CHANNEL_CLIENT(dcc)->client, + dcc->pixmap_cache = pixmap_cache_get(client, migrate_data->pixmap_cache_id, -1); spice_return_val_if_fail(dcc->pixmap_cache, FALSE); diff --git a/server/inputs-channel-client.c b/server/inputs-channel-client.c index 8a4b4dd..6712508 100644 --- a/server/inputs-channel-client.c +++ b/server/inputs-channel-client.c @@ -86,7 +86,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(RED_CHANNEL_CLIENT(icc)); if (++icc->priv->motion_count % SPICE_INPUT_MOTION_ACK_BUNCH == 0 && !inputs_channel_is_src_during_migrate(inputs_channel)) { diff --git a/server/main-channel-client.c b/server/main-channel-client.c index 4481168..23cf439 100644 --- a/server/main-channel-client.c +++ b/server/main-channel-client.c @@ -343,21 +343,23 @@ void main_channel_client_handle_migrate_connected(MainChannelClient *mcc, int success, int seamless) { - spice_printerr("client %p connected: %d seamless %d", mcc->base.client, success, seamless); + RedClient *client = red_channel_client_get_client(RED_CHANNEL_CLIENT(mcc)); + RedChannel *channel = red_channel_client_get_channel(RED_CHANNEL_CLIENT(mcc)); + spice_printerr("client %p connected: %d seamless %d", client, success, seamless); if (mcc->priv->mig_wait_connect) { - MainChannel *main_channel = SPICE_CONTAINEROF(mcc->base.channel, MainChannel, base); + MainChannel *main_channel = SPICE_CONTAINEROF(channel, MainChannel, base); mcc->priv->mig_wait_connect = FALSE; mcc->priv->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) { - spice_printerr("client %p MIGRATE_CANCEL", mcc->base.client); - red_channel_client_pipe_add_empty_msg(&mcc->base, SPICE_MSG_MAIN_MIGRATE_CANCEL); + spice_printerr("client %p MIGRATE_CANCEL", client); + red_channel_client_pipe_add_empty_msg(RED_CHANNEL_CLIENT(mcc), SPICE_MSG_MAIN_MIGRATE_CANCEL); } } } @@ -365,7 +367,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(RED_CHANNEL_CLIENT(mcc)); + if (reds_on_migrate_dst_set_seamless(channel->reds, mcc, src_version)) { mcc->priv->seamless_mig_dst = TRUE; red_channel_client_pipe_add_empty_msg(&mcc->base, SPICE_MSG_MAIN_MIGRATE_DST_SEAMLESS_ACK); @@ -432,13 +435,14 @@ 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 } void main_channel_client_handle_migrate_end(MainChannelClient *mcc) { - if (!red_client_during_migrate_at_target(mcc->base.client)) { + RedClient *client = red_channel_client_get_client(RED_CHANNEL_CLIENT(mcc)); + if (!red_client_during_migrate_at_target(client)) { spice_printerr("unexpected SPICE_MSGC_MIGRATE_END"); return; } @@ -448,13 +452,14 @@ void main_channel_client_handle_migrate_end(MainChannelClient *mcc) "client does not support semi-seamless migration"); return; } - red_client_semi_seamless_migrate_complete(mcc->base.client); + red_client_semi_seamless_migrate_complete(client); } void main_channel_client_migrate_cancel_wait(MainChannelClient *mcc) { + RedClient *client = red_channel_client_get_client(RED_CHANNEL_CLIENT(mcc)); if (mcc->priv->mig_wait_connect) { - spice_printerr("client %p cancel wait connect", mcc->base.client); + spice_printerr("client %p cancel wait connect", client); mcc->priv->mig_wait_connect = FALSE; mcc->priv->mig_connect_ok = FALSE; } @@ -463,9 +468,10 @@ void main_channel_client_migrate_cancel_wait(MainChannelClient *mcc) void main_channel_client_migrate_dst_complete(MainChannelClient *mcc) { + RedChannel *channel = red_channel_client_get_channel(RED_CHANNEL_CLIENT(mcc)); if (mcc->priv->mig_wait_prev_complete) { if (mcc->priv->mig_wait_prev_try_seamless) { - spice_assert(g_list_length(mcc->base.channel->clients) == 1); + 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 { @@ -479,21 +485,22 @@ void main_channel_client_migrate_dst_complete(MainChannelClient *mcc) gboolean main_channel_client_migrate_src_complete(MainChannelClient *mcc, gboolean success) { + RedClient *client = red_channel_client_get_client(RED_CHANNEL_CLIENT(mcc)); gboolean ret = FALSE; int semi_seamless_support = red_channel_client_test_remote_cap(&mcc->base, SPICE_MAIN_CAP_SEMI_SEAMLESS_MIGRATE); if (semi_seamless_support && mcc->priv->mig_connect_ok) { if (success) { - spice_printerr("client %p MIGRATE_END", mcc->base.client); + spice_printerr("client %p MIGRATE_END", client); red_channel_client_pipe_add_empty_msg(&mcc->base, SPICE_MSG_MAIN_MIGRATE_END); ret = TRUE; } else { - spice_printerr("client %p MIGRATE_CANCEL", mcc->base.client); + spice_printerr("client %p MIGRATE_CANCEL", client); red_channel_client_pipe_add_empty_msg(&mcc->base, SPICE_MSG_MAIN_MIGRATE_CANCEL); } } else { if (success) { - spice_printerr("client %p SWITCH_HOST", mcc->base.client); + spice_printerr("client %p SWITCH_HOST", client); red_channel_client_pipe_add_type(&mcc->base, RED_PIPE_ITEM_TYPE_MAIN_MIGRATE_SWITCH_HOST); } } @@ -507,6 +514,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(RED_CHANNEL_CLIENT(mcc)); spice_printerr(""); if (!opt) { main_channel_client_push_ping(mcc, 0); @@ -514,9 +522,9 @@ static void do_ping_client(MainChannelClient *mcc, if (has_interval && interval > 0) { mcc->priv->ping_interval = interval * MSEC_PER_SEC; } - reds_core_timer_start(mcc->base.channel->reds, mcc->priv->ping_timer, mcc->priv->ping_interval); + reds_core_timer_start(channel->reds, mcc->priv->ping_timer, mcc->priv->ping_interval); } else if (!strcmp(opt, "off")) { - reds_core_timer_cancel(mcc->base.channel->reds, mcc->priv->ping_timer); + reds_core_timer_cancel(channel->reds, mcc->priv->ping_timer); } else { return; } @@ -525,14 +533,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(RED_CHANNEL_CLIENT(mcc)); 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->priv->ping_timer); + reds_core_timer_cancel(channel->reds, mcc->priv->ping_timer); return; } do_ping_client(mcc, NULL, 0, 0); - reds_core_timer_start(mcc->base.channel->reds, mcc->priv->ping_timer, mcc->priv->ping_interval); + reds_core_timer_start(channel->reds, mcc->priv->ping_timer, mcc->priv->ping_interval); } #endif /* RED_STATISTICS */ @@ -581,14 +590,16 @@ 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 = SPICE_CONTAINEROF(red_channel_client_get_channel(rcc), + MainChannel, base); if (red_channel_client_test_remote_cap(rcc, SPICE_MAIN_CAP_SEMI_SEAMLESS_MIGRATE)) { RedClient *client = red_channel_client_get_client(rcc); @@ -610,10 +621,11 @@ gboolean main_channel_client_connect_semi_seamless(MainChannelClient *mcc) void main_channel_client_connect_seamless(MainChannelClient *mcc) { + RedClient *client = red_channel_client_get_client(RED_CHANNEL_CLIENT(mcc)); spice_assert(red_channel_client_test_remote_cap(&mcc->base, SPICE_MAIN_CAP_SEAMLESS_MIGRATE)); - if (red_client_during_migrate_at_target(mcc->base.client)) { - spice_printerr("client %p: wait till previous migration completes", mcc->base.client); + if (red_client_during_migrate_at_target(client)) { + spice_printerr("client %p: wait till previous migration completes", client); mcc->priv->mig_wait_prev_complete = TRUE; mcc->priv->mig_wait_prev_try_seamless = TRUE; } else { diff --git a/server/red-channel-client-private.h b/server/red-channel-client-private.h index 4ad4d90..2e73279 100644 --- a/server/red-channel-client-private.h +++ b/server/red-channel-client-private.h @@ -21,7 +21,18 @@ #include "red-channel-client.h" #include "red-channel.h" -struct RedChannelClient { +typedef struct RedChannelClientPrivate RedChannelClientPrivate; +struct RedChannelClient +{ + /* protected */ + OutgoingHandler outgoing; + IncomingHandler incoming; + + RedChannelClientPrivate *priv; +}; + +struct RedChannelClientPrivate +{ RedChannel *channel; RedClient *client; RedsStream *stream; @@ -57,8 +68,6 @@ struct RedChannelClient { } urgent; } send_data; - OutgoingHandler outgoing; - IncomingHandler incoming; int during_send; int id; // debugging purposes Ring pipe; diff --git a/server/red-channel-client.c b/server/red-channel-client.c index 908dc85..82afac8 100644 --- a/server/red-channel-client.c +++ b/server/red-channel-client.c @@ -65,34 +65,34 @@ typedef struct MarkerPipeItem { static void red_channel_client_start_ping_timer(RedChannelClient *rcc, uint32_t timeout) { - if (!rcc->latency_monitor.timer) { + if (!rcc->priv->latency_monitor.timer) { return; } - if (rcc->latency_monitor.state != PING_STATE_NONE) { + if (rcc->priv->latency_monitor.state != PING_STATE_NONE) { return; } - rcc->latency_monitor.state = PING_STATE_TIMER; - rcc->channel->core->timer_start(rcc->latency_monitor.timer, timeout); + rcc->priv->latency_monitor.state = PING_STATE_TIMER; + rcc->priv->channel->core->timer_start(rcc->priv->latency_monitor.timer, timeout); } static void red_channel_client_cancel_ping_timer(RedChannelClient *rcc) { - if (!rcc->latency_monitor.timer) { + if (!rcc->priv->latency_monitor.timer) { return; } - if (rcc->latency_monitor.state != PING_STATE_TIMER) { + if (rcc->priv->latency_monitor.state != PING_STATE_TIMER) { return; } - rcc->channel->core->timer_cancel(rcc->latency_monitor.timer); - rcc->latency_monitor.state = PING_STATE_NONE; + rcc->priv->channel->core->timer_cancel(rcc->priv->latency_monitor.timer); + rcc->priv->latency_monitor.state = PING_STATE_NONE; } static void red_channel_client_restart_ping_timer(RedChannelClient *rcc) { uint64_t passed, timeout; - passed = (spice_get_monotonic_time_ns() - rcc->latency_monitor.last_pong_time) / NSEC_PER_MILLISEC; + passed = (spice_get_monotonic_time_ns() - rcc->priv->latency_monitor.last_pong_time) / NSEC_PER_MILLISEC; timeout = PING_TEST_IDLE_NET_TIMEOUT_MS; if (passed < PING_TEST_TIMEOUT_MS) { timeout += PING_TEST_TIMEOUT_MS - passed; @@ -103,7 +103,7 @@ static void red_channel_client_restart_ping_timer(RedChannelClient *rcc) RedChannel* red_channel_client_get_channel(RedChannelClient* rcc) { - return rcc->channel; + return rcc->priv->channel; } IncomingHandler* red_channel_client_get_incoming_handler(RedChannelClient *rcc) @@ -115,18 +115,18 @@ void red_channel_client_on_output(void *opaque, int n) { RedChannelClient *rcc = opaque; - if (rcc->connectivity_monitor.timer) { - rcc->connectivity_monitor.out_bytes += n; + if (rcc->priv->connectivity_monitor.timer) { + rcc->priv->connectivity_monitor.out_bytes += n; } - stat_inc_counter(reds, rcc->channel->out_bytes_counter, n); + stat_inc_counter(reds, rcc->priv->channel->out_bytes_counter, n); } void red_channel_client_on_input(void *opaque, int n) { RedChannelClient *rcc = opaque; - if (rcc->connectivity_monitor.timer) { - rcc->connectivity_monitor.in_bytes += n; + if (rcc->priv->connectivity_monitor.timer) { + rcc->priv->connectivity_monitor.in_bytes += n; } } @@ -134,7 +134,7 @@ int red_channel_client_get_out_msg_size(void *opaque) { RedChannelClient *rcc = (RedChannelClient *)opaque; - return rcc->send_data.size; + return rcc->priv->send_data.size; } void red_channel_client_prepare_out_msg(void *opaque, struct iovec *vec, @@ -142,7 +142,7 @@ void red_channel_client_prepare_out_msg(void *opaque, struct iovec *vec, { RedChannelClient *rcc = (RedChannelClient *)opaque; - *vec_size = spice_marshaller_fill_iovec(rcc->send_data.marshaller, + *vec_size = spice_marshaller_fill_iovec(rcc->priv->send_data.marshaller, vec, IOV_MAX, pos); } @@ -150,46 +150,46 @@ void red_channel_client_on_out_block(void *opaque) { RedChannelClient *rcc = (RedChannelClient *)opaque; - rcc->send_data.blocked = TRUE; - rcc->channel->core->watch_update_mask(rcc->stream->watch, - SPICE_WATCH_EVENT_READ | - SPICE_WATCH_EVENT_WRITE); + rcc->priv->send_data.blocked = TRUE; + rcc->priv->channel->core->watch_update_mask(rcc->priv->stream->watch, + SPICE_WATCH_EVENT_READ | + SPICE_WATCH_EVENT_WRITE); } static inline int red_channel_client_urgent_marshaller_is_active(RedChannelClient *rcc) { - return (rcc->send_data.marshaller == rcc->send_data.urgent.marshaller); + return (rcc->priv->send_data.marshaller == rcc->priv->send_data.urgent.marshaller); } static void red_channel_client_reset_send_data(RedChannelClient *rcc) { - spice_marshaller_reset(rcc->send_data.marshaller); - rcc->send_data.header.data = spice_marshaller_reserve_space(rcc->send_data.marshaller, - rcc->send_data.header.header_size); - spice_marshaller_set_base(rcc->send_data.marshaller, rcc->send_data.header.header_size); - rcc->send_data.header.set_msg_type(&rcc->send_data.header, 0); - rcc->send_data.header.set_msg_size(&rcc->send_data.header, 0); + spice_marshaller_reset(rcc->priv->send_data.marshaller); + rcc->priv->send_data.header.data = spice_marshaller_reserve_space(rcc->priv->send_data.marshaller, + rcc->priv->send_data.header.header_size); + spice_marshaller_set_base(rcc->priv->send_data.marshaller, rcc->priv->send_data.header.header_size); + rcc->priv->send_data.header.set_msg_type(&rcc->priv->send_data.header, 0); + rcc->priv->send_data.header.set_msg_size(&rcc->priv->send_data.header, 0); /* Keeping the serial consecutive: resetting it if reset_send_data * has been called before, but no message has been sent since then. */ - if (rcc->send_data.last_sent_serial != rcc->send_data.serial) { - spice_assert(rcc->send_data.serial - rcc->send_data.last_sent_serial == 1); + if (rcc->priv->send_data.last_sent_serial != rcc->priv->send_data.serial) { + spice_assert(rcc->priv->send_data.serial - rcc->priv->send_data.last_sent_serial == 1); /* When the urgent marshaller is active, the serial was incremented by * the call to reset_send_data that was made for the main marshaller. * The urgent msg receives this serial, and the main msg serial is - * the following one. Thus, (rcc->send_data.serial - rcc->send_data.last_sent_serial) + * the following one. Thus, (rcc->priv->send_data.serial - rcc->priv->send_data.last_sent_serial) * should be 1 in this case*/ if (!red_channel_client_urgent_marshaller_is_active(rcc)) { - rcc->send_data.serial = rcc->send_data.last_sent_serial; + rcc->priv->send_data.serial = rcc->priv->send_data.last_sent_serial; } } - rcc->send_data.serial++; + rcc->priv->send_data.serial++; - if (!rcc->is_mini_header) { - spice_assert(rcc->send_data.marshaller != rcc->send_data.urgent.marshaller); - rcc->send_data.header.set_msg_sub_list(&rcc->send_data.header, 0); - rcc->send_data.header.set_msg_serial(&rcc->send_data.header, rcc->send_data.serial); + if (!rcc->priv->is_mini_header) { + spice_assert(rcc->priv->send_data.marshaller != rcc->priv->send_data.urgent.marshaller); + rcc->priv->send_data.header.set_msg_sub_list(&rcc->priv->send_data.header, 0); + rcc->priv->send_data.header.set_msg_serial(&rcc->priv->send_data.header, rcc->priv->send_data.serial); } } @@ -199,11 +199,11 @@ static void red_channel_client_send_set_ack(RedChannelClient *rcc) spice_assert(rcc); red_channel_client_init_send_data(rcc, SPICE_MSG_SET_ACK, NULL); - ack.generation = ++rcc->ack_data.generation; - ack.window = rcc->ack_data.client_window; - rcc->ack_data.messages_window = 0; + ack.generation = ++rcc->priv->ack_data.generation; + ack.window = rcc->priv->ack_data.client_window; + rcc->priv->ack_data.messages_window = 0; - spice_marshall_msg_set_ack(rcc->send_data.marshaller, &ack); + spice_marshall_msg_set_ack(rcc->priv->send_data.marshaller, &ack); red_channel_client_begin_send_message(rcc); } @@ -213,10 +213,10 @@ static void red_channel_client_send_migrate(RedChannelClient *rcc) SpiceMsgMigrate migrate; red_channel_client_init_send_data(rcc, SPICE_MSG_MIGRATE, NULL); - migrate.flags = rcc->channel->migration_flags; - spice_marshall_msg_migrate(rcc->send_data.marshaller, &migrate); - if (rcc->channel->migration_flags & SPICE_MIGRATE_NEED_FLUSH) { - rcc->wait_migrate_flush_mark = TRUE; + migrate.flags = rcc->priv->channel->migration_flags; + spice_marshall_msg_migrate(rcc->priv->send_data.marshaller, &migrate); + if (rcc->priv->channel->migration_flags & SPICE_MIGRATE_NEED_FLUSH) { + rcc->priv->wait_migrate_flush_mark = TRUE; } red_channel_client_begin_send_message(rcc); @@ -226,25 +226,25 @@ static void red_channel_client_send_ping(RedChannelClient *rcc) { SpiceMsgPing ping; - if (!rcc->latency_monitor.warmup_was_sent) { // latency test start + if (!rcc->priv->latency_monitor.warmup_was_sent) { // latency test start int delay_val; socklen_t opt_size = sizeof(delay_val); - rcc->latency_monitor.warmup_was_sent = TRUE; + rcc->priv->latency_monitor.warmup_was_sent = TRUE; /* * When testing latency, TCP_NODELAY must be switched on, otherwise, * sending the ping message is delayed by Nagle algorithm, and the * roundtrip measurment is less accurate (bigger). */ - rcc->latency_monitor.tcp_nodelay = 1; - if (getsockopt(rcc->stream->socket, IPPROTO_TCP, TCP_NODELAY, &delay_val, + rcc->priv->latency_monitor.tcp_nodelay = 1; + if (getsockopt(rcc->priv->stream->socket, IPPROTO_TCP, TCP_NODELAY, &delay_val, &opt_size) == -1) { spice_warning("getsockopt failed, %s", strerror(errno)); } else { - rcc->latency_monitor.tcp_nodelay = delay_val; + rcc->priv->latency_monitor.tcp_nodelay = delay_val; if (!delay_val) { delay_val = 1; - if (setsockopt(rcc->stream->socket, IPPROTO_TCP, TCP_NODELAY, &delay_val, + if (setsockopt(rcc->priv->stream->socket, IPPROTO_TCP, TCP_NODELAY, &delay_val, sizeof(delay_val)) == -1) { if (errno != ENOTSUP) { spice_warning("setsockopt failed, %s", strerror(errno)); @@ -255,9 +255,9 @@ static void red_channel_client_send_ping(RedChannelClient *rcc) } red_channel_client_init_send_data(rcc, SPICE_MSG_PING, NULL); - ping.id = rcc->latency_monitor.id; + ping.id = rcc->priv->latency_monitor.id; ping.timestamp = spice_get_monotonic_time_ns(); - spice_marshall_msg_ping(rcc->send_data.marshaller, &ping); + spice_marshall_msg_ping(rcc->priv->send_data.marshaller, &ping); red_channel_client_begin_send_message(rcc); } @@ -289,7 +289,7 @@ static void red_channel_client_send_item(RedChannelClient *rcc, RedPipeItem *ite case RED_PIPE_ITEM_TYPE_MARKER: break; default: - rcc->channel->channel_cbs.send_item(rcc, item); + rcc->priv->channel->channel_cbs.send_item(rcc, item); break; } red_pipe_item_unref(item); @@ -297,21 +297,22 @@ static void red_channel_client_send_item(RedChannelClient *rcc, RedPipeItem *ite static inline void red_channel_client_release_sent_item(RedChannelClient *rcc) { - if (rcc->send_data.item) { - red_pipe_item_unref(rcc->send_data.item); - rcc->send_data.item = NULL; + if (rcc->priv->send_data.item) { + red_pipe_item_unref(rcc->priv->send_data.item); + rcc->priv->send_data.item = NULL; } } static void red_channel_client_restore_main_sender(RedChannelClient *rcc) { - spice_marshaller_reset(rcc->send_data.urgent.marshaller); - rcc->send_data.marshaller = rcc->send_data.main.marshaller; - rcc->send_data.header.data = rcc->send_data.main.header_data; - if (!rcc->is_mini_header) { - rcc->send_data.header.set_msg_serial(&rcc->send_data.header, rcc->send_data.serial); + spice_marshaller_reset(rcc->priv->send_data.urgent.marshaller); + rcc->priv->send_data.marshaller = rcc->priv->send_data.main.marshaller; + rcc->priv->send_data.header.data = rcc->priv->send_data.main.header_data; + if (!rcc->priv->is_mini_header) { + rcc->priv->send_data.header.set_msg_serial(&rcc->priv->send_data.header, + rcc->priv->send_data.serial); } - rcc->send_data.item = rcc->send_data.main.item; + rcc->priv->send_data.item = rcc->priv->send_data.main.item; } void red_channel_client_on_out_msg_done(void *opaque) @@ -319,10 +320,10 @@ void red_channel_client_on_out_msg_done(void *opaque) RedChannelClient *rcc = (RedChannelClient *)opaque; int fd; - rcc->send_data.size = 0; + rcc->priv->send_data.size = 0; - if (spice_marshaller_get_fd(rcc->send_data.marshaller, &fd)) { - if (reds_stream_send_msgfd(rcc->stream, fd) < 0) { + if (spice_marshaller_get_fd(rcc->priv->send_data.marshaller, &fd)) { + if (reds_stream_send_msgfd(rcc->priv->stream, fd) < 0) { perror("sendfd"); red_channel_client_disconnect(rcc); if (fd != -1) @@ -334,18 +335,20 @@ void red_channel_client_on_out_msg_done(void *opaque) } red_channel_client_release_sent_item(rcc); - if (rcc->send_data.blocked) { - rcc->send_data.blocked = FALSE; - rcc->channel->core->watch_update_mask(rcc->stream->watch, - SPICE_WATCH_EVENT_READ); + if (rcc->priv->send_data.blocked) { + rcc->priv->send_data.blocked = FALSE; + rcc->priv->channel->core->watch_update_mask(rcc->priv->stream->watch, + SPICE_WATCH_EVENT_READ); } if (red_channel_client_urgent_marshaller_is_active(rcc)) { red_channel_client_restore_main_sender(rcc); - spice_assert(rcc->send_data.header.data != NULL); + spice_assert(rcc->priv->send_data.header.data != NULL); red_channel_client_begin_send_message(rcc); } else { - if (rcc->latency_monitor.timer && !rcc->send_data.blocked && rcc->pipe_size == 0) { + if (rcc->priv->latency_monitor.timer + && !rcc->priv->send_data.blocked + && rcc->priv->pipe_size == 0) { /* It is possible that the socket will become idle, so we may be able to test latency */ red_channel_client_restart_ping_timer(rcc); } @@ -355,7 +358,7 @@ void red_channel_client_on_out_msg_done(void *opaque) static void red_channel_client_pipe_remove(RedChannelClient *rcc, RedPipeItem *item) { - rcc->pipe_size--; + rcc->priv->pipe_size--; ring_remove(&item->link); } @@ -363,41 +366,43 @@ static void red_channel_client_set_remote_caps(RedChannelClient* rcc, int num_common_caps, uint32_t *common_caps, int num_caps, uint32_t *caps) { - rcc->remote_caps.num_common_caps = num_common_caps; - rcc->remote_caps.common_caps = spice_memdup(common_caps, num_common_caps * sizeof(uint32_t)); + rcc->priv->remote_caps.num_common_caps = num_common_caps; + rcc->priv->remote_caps.common_caps = spice_memdup(common_caps, + num_common_caps * + sizeof(uint32_t)); - rcc->remote_caps.num_caps = num_caps; - rcc->remote_caps.caps = spice_memdup(caps, num_caps * sizeof(uint32_t)); + rcc->priv->remote_caps.num_caps = num_caps; + rcc->priv->remote_caps.caps = spice_memdup(caps, num_caps * sizeof(uint32_t)); } static void red_channel_client_destroy_remote_caps(RedChannelClient* rcc) { - rcc->remote_caps.num_common_caps = 0; - free(rcc->remote_caps.common_caps); - rcc->remote_caps.num_caps = 0; - free(rcc->remote_caps.caps); + rcc->priv->remote_caps.num_common_caps = 0; + free(rcc->priv->remote_caps.common_caps); + rcc->priv->remote_caps.num_caps = 0; + free(rcc->priv->remote_caps.caps); } int red_channel_client_test_remote_common_cap(RedChannelClient *rcc, uint32_t cap) { - return test_capability(rcc->remote_caps.common_caps, - rcc->remote_caps.num_common_caps, + return test_capability(rcc->priv->remote_caps.common_caps, + rcc->priv->remote_caps.num_common_caps, cap); } int red_channel_client_test_remote_cap(RedChannelClient *rcc, uint32_t cap) { - return test_capability(rcc->remote_caps.caps, - rcc->remote_caps.num_caps, + return test_capability(rcc->priv->remote_caps.caps, + rcc->priv->remote_caps.num_caps, cap); } static void red_channel_client_push_ping(RedChannelClient *rcc) { - spice_assert(rcc->latency_monitor.state == PING_STATE_NONE); - rcc->latency_monitor.state = PING_STATE_WARMUP; - rcc->latency_monitor.warmup_was_sent = FALSE; - rcc->latency_monitor.id = rand(); + spice_assert(rcc->priv->latency_monitor.state == PING_STATE_NONE); + rcc->priv->latency_monitor.state = PING_STATE_WARMUP; + rcc->priv->latency_monitor.warmup_was_sent = FALSE; + rcc->priv->latency_monitor.id = rand(); red_channel_client_pipe_add_type(rcc, RED_PIPE_ITEM_TYPE_PING); red_channel_client_pipe_add_type(rcc, RED_PIPE_ITEM_TYPE_PING); } @@ -406,7 +411,7 @@ static void red_channel_client_ping_timer(void *opaque) { RedChannelClient *rcc = opaque; - spice_assert(rcc->latency_monitor.state == PING_STATE_TIMER); + spice_assert(rcc->priv->latency_monitor.state == PING_STATE_TIMER); red_channel_client_cancel_ping_timer(rcc); #ifdef HAVE_LINUX_SOCKIOS_H /* SIOCOUTQ is a Linux only ioctl on sockets. */ @@ -414,7 +419,7 @@ static void red_channel_client_ping_timer(void *opaque) int so_unsent_size = 0; /* retrieving the occupied size of the socket's tcp snd buffer (unacked + unsent) */ - if (ioctl(rcc->stream->socket, SIOCOUTQ, &so_unsent_size) == -1) { + if (ioctl(rcc->priv->stream->socket, SIOCOUTQ, &so_unsent_size) == -1) { spice_printerr("ioctl(SIOCOUTQ) failed, %s", strerror(errno)); } if (so_unsent_size > 0) { @@ -432,8 +437,8 @@ static void red_channel_client_ping_timer(void *opaque) static inline int red_channel_client_waiting_for_ack(RedChannelClient *rcc) { - return (rcc->channel->handle_acks && - (rcc->ack_data.messages_window > rcc->ack_data.client_window * 2)); + return (rcc->priv->channel->handle_acks && + (rcc->priv->ack_data.messages_window > rcc->priv->ack_data.client_window * 2)); } /* @@ -451,12 +456,12 @@ static inline int red_channel_client_waiting_for_ack(RedChannelClient *rcc) static void red_channel_client_connectivity_timer(void *opaque) { RedChannelClient *rcc = opaque; - RedChannelClientConnectivityMonitor *monitor = &rcc->connectivity_monitor; + RedChannelClientConnectivityMonitor *monitor = &rcc->priv->connectivity_monitor; int is_alive = TRUE; if (monitor->state == CONNECTIVITY_STATE_BLOCKED) { if (monitor->in_bytes == 0 && monitor->out_bytes == 0) { - if (!rcc->send_data.blocked && !red_channel_client_waiting_for_ack(rcc)) { + if (!rcc->priv->send_data.blocked && !red_channel_client_waiting_for_ack(rcc)) { spice_error("mismatch between rcc-state and connectivity-state"); } spice_debug("rcc is blocked; connection is idle"); @@ -464,8 +469,8 @@ static void red_channel_client_connectivity_timer(void *opaque) } } else if (monitor->state == CONNECTIVITY_STATE_WAIT_PONG) { if (monitor->in_bytes == 0) { - if (rcc->latency_monitor.state != PING_STATE_WARMUP && - rcc->latency_monitor.state != PING_STATE_LATENCY) { + if (rcc->priv->latency_monitor.state != PING_STATE_WARMUP && + rcc->priv->latency_monitor.state != PING_STATE_LATENCY) { spice_error("mismatch between rcc-state and connectivity-state"); } spice_debug("rcc waits for pong; connection is idle"); @@ -476,20 +481,20 @@ static void red_channel_client_connectivity_timer(void *opaque) if (is_alive) { monitor->in_bytes = 0; monitor->out_bytes = 0; - if (rcc->send_data.blocked || red_channel_client_waiting_for_ack(rcc)) { + if (rcc->priv->send_data.blocked || red_channel_client_waiting_for_ack(rcc)) { monitor->state = CONNECTIVITY_STATE_BLOCKED; - } else if (rcc->latency_monitor.state == PING_STATE_WARMUP || - rcc->latency_monitor.state == PING_STATE_LATENCY) { + } else if (rcc->priv->latency_monitor.state == PING_STATE_WARMUP || + rcc->priv->latency_monitor.state == PING_STATE_LATENCY) { monitor->state = CONNECTIVITY_STATE_WAIT_PONG; } else { monitor->state = CONNECTIVITY_STATE_CONNECTED; } - rcc->channel->core->timer_start(rcc->connectivity_monitor.timer, - rcc->connectivity_monitor.timeout); + rcc->priv->channel->core->timer_start(rcc->priv->connectivity_monitor.timer, + rcc->priv->connectivity_monitor.timeout); } else { monitor->state = CONNECTIVITY_STATE_DISCONNECTED; spice_warning("rcc %p on channel %d:%d has been unresponsive for more than %u ms, disconnecting", - rcc, rcc->channel->type, rcc->channel->id, monitor->timeout); + rcc, rcc->priv->channel->type, rcc->priv->channel->id, monitor->timeout); red_channel_client_disconnect(rcc); } } @@ -507,22 +512,22 @@ void red_channel_client_start_connectivity_monitoring(RedChannelClient *rcc, uin * channel-client even if there are no ongoing channel specific messages * on this channel. */ - if (rcc->latency_monitor.timer == NULL) { - rcc->latency_monitor.timer = rcc->channel->core->timer_add( - rcc->channel->core, red_channel_client_ping_timer, rcc); - if (!red_client_during_migrate_at_target(rcc->client)) { + if (rcc->priv->latency_monitor.timer == NULL) { + rcc->priv->latency_monitor.timer = rcc->priv->channel->core->timer_add( + rcc->priv->channel->core, red_channel_client_ping_timer, rcc); + if (!red_client_during_migrate_at_target(rcc->priv->client)) { red_channel_client_start_ping_timer(rcc, PING_TEST_IDLE_NET_TIMEOUT_MS); } - rcc->latency_monitor.roundtrip = -1; - } - if (rcc->connectivity_monitor.timer == NULL) { - rcc->connectivity_monitor.state = CONNECTIVITY_STATE_CONNECTED; - rcc->connectivity_monitor.timer = rcc->channel->core->timer_add( - rcc->channel->core, red_channel_client_connectivity_timer, rcc); - rcc->connectivity_monitor.timeout = timeout_ms; - if (!red_client_during_migrate_at_target(rcc->client)) { - rcc->channel->core->timer_start(rcc->connectivity_monitor.timer, - rcc->connectivity_monitor.timeout); + rcc->priv->latency_monitor.roundtrip = -1; + } + if (rcc->priv->connectivity_monitor.timer == NULL) { + rcc->priv->connectivity_monitor.state = CONNECTIVITY_STATE_CONNECTED; + rcc->priv->connectivity_monitor.timer = rcc->priv->channel->core->timer_add( + rcc->priv->channel->core, red_channel_client_connectivity_timer, rcc); + rcc->priv->connectivity_monitor.timeout = timeout_ms; + if (!red_client_during_migrate_at_target(rcc->priv->client)) { + rcc->priv->channel->core->timer_start(rcc->priv->connectivity_monitor.timer, + rcc->priv->connectivity_monitor.timeout); } } } @@ -641,18 +646,19 @@ RedChannelClient *red_channel_client_create(int size, RedChannel *channel, RedCl } spice_assert(stream && channel && size >= sizeof(RedChannelClient)); rcc = spice_malloc0(size); - rcc->stream = stream; - rcc->channel = channel; - rcc->client = client; - rcc->refs = 1; - rcc->ack_data.messages_window = ~0; // blocks send message (maybe use send_data.blocked + - // block flags) - rcc->ack_data.client_generation = ~0; - rcc->ack_data.client_window = CLIENT_ACK_WINDOW; - rcc->send_data.main.marshaller = spice_marshaller_new(); - rcc->send_data.urgent.marshaller = spice_marshaller_new(); - - rcc->send_data.marshaller = rcc->send_data.main.marshaller; + rcc->priv = g_new0(RedChannelClientPrivate, 1); + rcc->priv->stream = stream; + rcc->priv->channel = channel; + rcc->priv->client = client; + rcc->priv->refs = 1; + rcc->priv->ack_data.messages_window = ~0; // blocks send message (maybe use send_data.blocked + + // block flags) + rcc->priv->ack_data.client_generation = ~0; + rcc->priv->ack_data.client_window = CLIENT_ACK_WINDOW; + rcc->priv->send_data.main.marshaller = spice_marshaller_new(); + rcc->priv->send_data.urgent.marshaller = spice_marshaller_new(); + + rcc->priv->send_data.marshaller = rcc->priv->send_data.main.marshaller; rcc->incoming.opaque = rcc; rcc->incoming.cb = &channel->incoming_cb; @@ -665,12 +671,12 @@ RedChannelClient *red_channel_client_create(int size, RedChannel *channel, RedCl red_channel_client_set_remote_caps(rcc, num_common_caps, common_caps, num_caps, caps); if (red_channel_client_test_remote_common_cap(rcc, SPICE_COMMON_CAP_MINI_HEADER)) { rcc->incoming.header = mini_header_wrapper; - rcc->send_data.header = mini_header_wrapper; - rcc->is_mini_header = TRUE; + rcc->priv->send_data.header = mini_header_wrapper; + rcc->priv->is_mini_header = TRUE; } else { rcc->incoming.header = full_header_wrapper; - rcc->send_data.header = full_header_wrapper; - rcc->is_mini_header = FALSE; + rcc->priv->send_data.header = full_header_wrapper; + rcc->priv->is_mini_header = FALSE; } rcc->incoming.header.data = rcc->incoming.header_buf; @@ -680,26 +686,26 @@ RedChannelClient *red_channel_client_create(int size, RedChannel *channel, RedCl goto error; } - ring_init(&rcc->pipe); - rcc->pipe_size = 0; + ring_init(&rcc->priv->pipe); + rcc->priv->pipe_size = 0; stream->watch = channel->core->watch_add(channel->core, stream->socket, SPICE_WATCH_EVENT_READ, red_channel_client_event, rcc); - rcc->id = g_list_length(channel->clients); + rcc->priv->id = g_list_length(channel->clients); red_channel_add_client(channel, rcc); red_client_add_channel(client, rcc); red_channel_ref(channel); pthread_mutex_unlock(&client->lock); if (monitor_latency && reds_stream_get_family(stream) != AF_UNIX) { - rcc->latency_monitor.timer = channel->core->timer_add( + rcc->priv->latency_monitor.timer = channel->core->timer_add( channel->core, red_channel_client_ping_timer, rcc); if (!client->during_target_migrate) { red_channel_client_start_ping_timer(rcc, PING_TEST_IDLE_NET_TIMEOUT_MS); } - rcc->latency_monitor.roundtrip = -1; + rcc->priv->latency_monitor.roundtrip = -1; } return rcc; @@ -725,27 +731,28 @@ RedChannelClient *red_channel_client_create_dummy(int size, goto error; } rcc = spice_malloc0(size); - rcc->refs = 1; - rcc->client = client; - rcc->channel = channel; + rcc->priv = g_new0(RedChannelClientPrivate, 1); + rcc->priv->refs = 1; + rcc->priv->client = client; + rcc->priv->channel = channel; red_channel_ref(channel); red_channel_client_set_remote_caps(rcc, num_common_caps, common_caps, num_caps, caps); if (red_channel_client_test_remote_common_cap(rcc, SPICE_COMMON_CAP_MINI_HEADER)) { rcc->incoming.header = mini_header_wrapper; - rcc->send_data.header = mini_header_wrapper; - rcc->is_mini_header = TRUE; + rcc->priv->send_data.header = mini_header_wrapper; + rcc->priv->is_mini_header = TRUE; } else { rcc->incoming.header = full_header_wrapper; - rcc->send_data.header = full_header_wrapper; - rcc->is_mini_header = FALSE; + rcc->priv->send_data.header = full_header_wrapper; + rcc->priv->is_mini_header = FALSE; } rcc->incoming.header.data = rcc->incoming.header_buf; rcc->incoming.serial = 1; - ring_init(&rcc->pipe); + ring_init(&rcc->priv->pipe); - rcc->dummy = TRUE; - rcc->dummy_connected = TRUE; + rcc->priv->dummy = TRUE; + rcc->priv->dummy_connected = TRUE; red_channel_add_client(channel, rcc); red_client_add_channel(client, rcc); pthread_mutex_unlock(&client->lock); @@ -757,79 +764,79 @@ error: void red_channel_client_seamless_migration_done(RedChannelClient *rcc) { - rcc->wait_migrate_data = FALSE; + rcc->priv->wait_migrate_data = FALSE; - if (red_client_seamless_migration_done_for_channel(rcc->client)) { - if (rcc->latency_monitor.timer) { + if (red_client_seamless_migration_done_for_channel(rcc->priv->client)) { + if (rcc->priv->latency_monitor.timer) { red_channel_client_start_ping_timer(rcc, PING_TEST_IDLE_NET_TIMEOUT_MS); } - if (rcc->connectivity_monitor.timer) { - rcc->channel->core->timer_start(rcc->connectivity_monitor.timer, - rcc->connectivity_monitor.timeout); + if (rcc->priv->connectivity_monitor.timer) { + rcc->priv->channel->core->timer_start(rcc->priv->connectivity_monitor.timer, + rcc->priv->connectivity_monitor.timeout); } } } void red_channel_client_semi_seamless_migration_complete(RedChannelClient *rcc) { - if (rcc->latency_monitor.timer) { + if (rcc->priv->latency_monitor.timer) { red_channel_client_start_ping_timer(rcc, PING_TEST_IDLE_NET_TIMEOUT_MS); } } int red_channel_client_is_waiting_for_migrate_data(RedChannelClient *rcc) { - return rcc->wait_migrate_data; + return rcc->priv->wait_migrate_data; } void red_channel_client_default_migrate(RedChannelClient *rcc) { - if (rcc->latency_monitor.timer) { + if (rcc->priv->latency_monitor.timer) { red_channel_client_cancel_ping_timer(rcc); - rcc->channel->core->timer_remove(rcc->latency_monitor.timer); - rcc->latency_monitor.timer = NULL; + rcc->priv->channel->core->timer_remove(rcc->priv->latency_monitor.timer); + rcc->priv->latency_monitor.timer = NULL; } - if (rcc->connectivity_monitor.timer) { - rcc->channel->core->timer_remove(rcc->connectivity_monitor.timer); - rcc->connectivity_monitor.timer = NULL; + if (rcc->priv->connectivity_monitor.timer) { + rcc->priv->channel->core->timer_remove(rcc->priv->connectivity_monitor.timer); + rcc->priv->connectivity_monitor.timer = NULL; } red_channel_client_pipe_add_type(rcc, RED_PIPE_ITEM_TYPE_MIGRATE); } void red_channel_client_ref(RedChannelClient *rcc) { - rcc->refs++; + rcc->priv->refs++; } void red_channel_client_unref(RedChannelClient *rcc) { - if (--rcc->refs != 0) { + if (--rcc->priv->refs != 0) { return; } spice_debug("destroy rcc=%p", rcc); - reds_stream_free(rcc->stream); - rcc->stream = NULL; + reds_stream_free(rcc->priv->stream); + rcc->priv->stream = NULL; - if (rcc->send_data.main.marshaller) { - spice_marshaller_destroy(rcc->send_data.main.marshaller); + if (rcc->priv->send_data.main.marshaller) { + spice_marshaller_destroy(rcc->priv->send_data.main.marshaller); } - if (rcc->send_data.urgent.marshaller) { - spice_marshaller_destroy(rcc->send_data.urgent.marshaller); + if (rcc->priv->send_data.urgent.marshaller) { + spice_marshaller_destroy(rcc->priv->send_data.urgent.marshaller); } red_channel_client_destroy_remote_caps(rcc); - if (rcc->channel) { - red_channel_unref(rcc->channel); + if (rcc->priv->channel) { + red_channel_unref(rcc->priv->channel); } free(rcc); } void red_channel_client_destroy(RedChannelClient *rcc) { - rcc->destroying = TRUE; + rcc->priv->destroying = TRUE; red_channel_client_disconnect(rcc); red_client_remove_channel(rcc); red_channel_client_unref(rcc); @@ -837,11 +844,11 @@ void red_channel_client_destroy(RedChannelClient *rcc) void red_channel_client_shutdown(RedChannelClient *rcc) { - if (rcc->stream && !rcc->stream->shutdown) { - rcc->channel->core->watch_remove(rcc->stream->watch); - rcc->stream->watch = NULL; - shutdown(rcc->stream->socket, SHUT_RDWR); - rcc->stream->shutdown = TRUE; + if (rcc->priv->stream && !rcc->priv->stream->shutdown) { + rcc->priv->channel->core->watch_remove(rcc->priv->stream->watch); + rcc->priv->stream->watch = NULL; + shutdown(rcc->priv->stream->socket, SHUT_RDWR); + rcc->priv->stream->shutdown = TRUE; } } @@ -1025,14 +1032,14 @@ static void red_peer_handle_incoming(RedsStream *stream, IncomingHandler *handle void red_channel_client_receive(RedChannelClient *rcc) { red_channel_client_ref(rcc); - red_peer_handle_incoming(rcc->stream, &rcc->incoming); + red_peer_handle_incoming(rcc->priv->stream, &rcc->incoming); red_channel_client_unref(rcc); } void red_channel_client_send(RedChannelClient *rcc) { red_channel_client_ref(rcc); - red_peer_handle_outgoing(rcc->stream, &rcc->outgoing); + red_peer_handle_outgoing(rcc->priv->stream, &rcc->outgoing); red_channel_client_unref(rcc); } @@ -1040,9 +1047,9 @@ static inline RedPipeItem *red_channel_client_pipe_item_get(RedChannelClient *rc { RedPipeItem *item; - if (!rcc || rcc->send_data.blocked + if (!rcc || rcc->priv->send_data.blocked || red_channel_client_waiting_for_ack(rcc) - || !(item = (RedPipeItem *)ring_get_tail(&rcc->pipe))) { + || !(item = (RedPipeItem *)ring_get_tail(&rcc->priv->pipe))) { return NULL; } red_channel_client_pipe_remove(rcc, item); @@ -1053,44 +1060,44 @@ void red_channel_client_push(RedChannelClient *rcc) { RedPipeItem *pipe_item; - if (!rcc->during_send) { - rcc->during_send = TRUE; + if (!rcc->priv->during_send) { + rcc->priv->during_send = TRUE; } else { return; } red_channel_client_ref(rcc); - if (rcc->send_data.blocked) { + if (rcc->priv->send_data.blocked) { red_channel_client_send(rcc); } - if (!red_channel_client_no_item_being_sent(rcc) && !rcc->send_data.blocked) { - rcc->send_data.blocked = TRUE; + if (!red_channel_client_no_item_being_sent(rcc) && !rcc->priv->send_data.blocked) { + rcc->priv->send_data.blocked = TRUE; spice_printerr("ERROR: an item waiting to be sent and not blocked"); } while ((pipe_item = red_channel_client_pipe_item_get(rcc))) { red_channel_client_send_item(rcc, pipe_item); } - if (red_channel_client_no_item_being_sent(rcc) && ring_is_empty(&rcc->pipe) - && rcc->stream->watch) { - rcc->channel->core->watch_update_mask(rcc->stream->watch, - SPICE_WATCH_EVENT_READ); + if (red_channel_client_no_item_being_sent(rcc) && ring_is_empty(&rcc->priv->pipe) + && rcc->priv->stream->watch) { + rcc->priv->channel->core->watch_update_mask(rcc->priv->stream->watch, + SPICE_WATCH_EVENT_READ); } - rcc->during_send = FALSE; + rcc->priv->during_send = FALSE; red_channel_client_unref(rcc); } int red_channel_client_get_roundtrip_ms(RedChannelClient *rcc) { - if (rcc->latency_monitor.roundtrip < 0) { - return rcc->latency_monitor.roundtrip; + if (rcc->priv->latency_monitor.roundtrip < 0) { + return rcc->priv->latency_monitor.roundtrip; } - return rcc->latency_monitor.roundtrip / NSEC_PER_MILLISEC; + return rcc->priv->latency_monitor.roundtrip / NSEC_PER_MILLISEC; } void red_channel_client_init_outgoing_messages_window(RedChannelClient *rcc) { - rcc->ack_data.messages_window = 0; + rcc->priv->ack_data.messages_window = 0; red_channel_client_push(rcc); } @@ -1100,27 +1107,27 @@ static void red_channel_client_handle_pong(RedChannelClient *rcc, SpiceMsgPing * /* ignoring unexpected pongs, or post-migration pongs for pings that * started just before migration */ - if (ping->id != rcc->latency_monitor.id) { + if (ping->id != rcc->priv->latency_monitor.id) { spice_warning("ping-id (%u)!= pong-id %u", - rcc->latency_monitor.id, ping->id); + rcc->priv->latency_monitor.id, ping->id); return; } now = spice_get_monotonic_time_ns(); - if (rcc->latency_monitor.state == PING_STATE_WARMUP) { - rcc->latency_monitor.state = PING_STATE_LATENCY; + if (rcc->priv->latency_monitor.state == PING_STATE_WARMUP) { + rcc->priv->latency_monitor.state = PING_STATE_LATENCY; return; - } else if (rcc->latency_monitor.state != PING_STATE_LATENCY) { + } else if (rcc->priv->latency_monitor.state != PING_STATE_LATENCY) { spice_warning("unexpected"); return; } /* set TCP_NODELAY=0, in case we reverted it for the test*/ - if (!rcc->latency_monitor.tcp_nodelay) { + if (!rcc->priv->latency_monitor.tcp_nodelay) { int delay_val = 0; - if (setsockopt(rcc->stream->socket, IPPROTO_TCP, TCP_NODELAY, &delay_val, + if (setsockopt(rcc->priv->stream->socket, IPPROTO_TCP, TCP_NODELAY, &delay_val, sizeof(delay_val)) == -1) { if (errno != ENOTSUP) { spice_warning("setsockopt failed, %s", strerror(errno)); @@ -1134,14 +1141,14 @@ static void red_channel_client_handle_pong(RedChannelClient *rcc, SpiceMsgPing * * threads or processes that are utilizing the network. We update the roundtrip * measurement with the minimal value we encountered till now. */ - if (rcc->latency_monitor.roundtrip < 0 || - now - ping->timestamp < rcc->latency_monitor.roundtrip) { - rcc->latency_monitor.roundtrip = now - ping->timestamp; - spice_debug("update roundtrip %.2f(ms)", ((double)rcc->latency_monitor.roundtrip)/NSEC_PER_MILLISEC); + if (rcc->priv->latency_monitor.roundtrip < 0 || + now - ping->timestamp < rcc->priv->latency_monitor.roundtrip) { + rcc->priv->latency_monitor.roundtrip = now - ping->timestamp; + spice_debug("update roundtrip %.2f(ms)", ((double)rcc->priv->latency_monitor.roundtrip)/NSEC_PER_MILLISEC); } - rcc->latency_monitor.last_pong_time = now; - rcc->latency_monitor.state = PING_STATE_NONE; + rcc->priv->latency_monitor.last_pong_time = now; + rcc->priv->latency_monitor.state = PING_STATE_NONE; red_channel_client_start_ping_timer(rcc, PING_TEST_TIMEOUT_MS); } @@ -1193,23 +1200,23 @@ int red_channel_client_handle_message(RedChannelClient *rcc, uint32_t size, spice_printerr("bad message size"); return FALSE; } - rcc->ack_data.client_generation = *(uint32_t *)(message); + rcc->priv->ack_data.client_generation = *(uint32_t *)(message); break; case SPICE_MSGC_ACK: - if (rcc->ack_data.client_generation == rcc->ack_data.generation) { - rcc->ack_data.messages_window -= rcc->ack_data.client_window; + if (rcc->priv->ack_data.client_generation == rcc->priv->ack_data.generation) { + rcc->priv->ack_data.messages_window -= rcc->priv->ack_data.client_window; red_channel_client_push(rcc); } break; case SPICE_MSGC_DISCONNECTING: break; case SPICE_MSGC_MIGRATE_FLUSH_MARK: - if (!rcc->wait_migrate_flush_mark) { + if (!rcc->priv->wait_migrate_flush_mark) { spice_error("unexpected flush mark"); return FALSE; } red_channel_handle_migrate_flush_mark(rcc); - rcc->wait_migrate_flush_mark = FALSE; + rcc->priv->wait_migrate_flush_mark = FALSE; break; case SPICE_MSGC_MIGRATE_DATA: red_channel_handle_migrate_data(rcc, size, message); @@ -1228,8 +1235,8 @@ void red_channel_client_init_send_data(RedChannelClient *rcc, uint16_t msg_type, { spice_assert(red_channel_client_no_item_being_sent(rcc)); spice_assert(msg_type != 0); - rcc->send_data.header.set_msg_type(&rcc->send_data.header, msg_type); - rcc->send_data.item = item; + rcc->priv->send_data.header.set_msg_type(&rcc->priv->send_data.header, msg_type); + rcc->priv->send_data.item = item; if (item) { red_pipe_item_ref(item); } @@ -1237,10 +1244,10 @@ void red_channel_client_init_send_data(RedChannelClient *rcc, uint16_t msg_type, void red_channel_client_begin_send_message(RedChannelClient *rcc) { - SpiceMarshaller *m = rcc->send_data.marshaller; + SpiceMarshaller *m = rcc->priv->send_data.marshaller; // TODO - better check: type in channel_allowed_types. Better: type in channel_allowed_types(channel_state) - if (rcc->send_data.header.get_msg_type(&rcc->send_data.header) == 0) { + if (rcc->priv->send_data.header.get_msg_type(&rcc->priv->send_data.header) == 0) { spice_printerr("BUG: header->type == 0"); return; } @@ -1249,37 +1256,38 @@ void red_channel_client_begin_send_message(RedChannelClient *rcc) red_channel_client_cancel_ping_timer(rcc); spice_marshaller_flush(m); - rcc->send_data.size = spice_marshaller_get_total_size(m); - rcc->send_data.header.set_msg_size(&rcc->send_data.header, - rcc->send_data.size - rcc->send_data.header.header_size); - rcc->ack_data.messages_window++; - rcc->send_data.last_sent_serial = rcc->send_data.serial; - rcc->send_data.header.data = NULL; /* avoid writing to this until we have a new message */ + rcc->priv->send_data.size = spice_marshaller_get_total_size(m); + rcc->priv->send_data.header.set_msg_size(&rcc->priv->send_data.header, + rcc->priv->send_data.size - + rcc->priv->send_data.header.header_size); + rcc->priv->ack_data.messages_window++; + rcc->priv->send_data.last_sent_serial = rcc->priv->send_data.serial; + rcc->priv->send_data.header.data = NULL; /* avoid writing to this until we have a new message */ red_channel_client_send(rcc); } SpiceMarshaller *red_channel_client_switch_to_urgent_sender(RedChannelClient *rcc) { spice_assert(red_channel_client_no_item_being_sent(rcc)); - spice_assert(rcc->send_data.header.data != NULL); - rcc->send_data.main.header_data = rcc->send_data.header.data; - rcc->send_data.main.item = rcc->send_data.item; + spice_assert(rcc->priv->send_data.header.data != NULL); + rcc->priv->send_data.main.header_data = rcc->priv->send_data.header.data; + rcc->priv->send_data.main.item = rcc->priv->send_data.item; - rcc->send_data.marshaller = rcc->send_data.urgent.marshaller; - rcc->send_data.item = NULL; + rcc->priv->send_data.marshaller = rcc->priv->send_data.urgent.marshaller; + rcc->priv->send_data.item = NULL; red_channel_client_reset_send_data(rcc); - return rcc->send_data.marshaller; + return rcc->priv->send_data.marshaller; } uint64_t red_channel_client_get_message_serial(RedChannelClient *rcc) { - return rcc->send_data.serial; + return rcc->priv->send_data.serial; } void red_channel_client_set_message_serial(RedChannelClient *rcc, uint64_t serial) { - rcc->send_data.last_sent_serial = serial; - rcc->send_data.serial = serial; + rcc->priv->send_data.last_sent_serial = serial; + rcc->priv->send_data.serial = serial; } static inline gboolean client_pipe_add(RedChannelClient *rcc, RedPipeItem *item, RingItem *pos) @@ -1290,12 +1298,12 @@ static inline gboolean client_pipe_add(RedChannelClient *rcc, RedPipeItem *item, red_pipe_item_unref(item); return FALSE; } - if (ring_is_empty(&rcc->pipe) && rcc->stream->watch) { - rcc->channel->core->watch_update_mask(rcc->stream->watch, - SPICE_WATCH_EVENT_READ | - SPICE_WATCH_EVENT_WRITE); + if (ring_is_empty(&rcc->priv->pipe) && rcc->priv->stream->watch) { + rcc->priv->channel->core->watch_update_mask(rcc->priv->stream->watch, + SPICE_WATCH_EVENT_READ | + SPICE_WATCH_EVENT_WRITE); } - rcc->pipe_size++; + rcc->priv->pipe_size++; ring_add(pos, &item->link); return TRUE; } @@ -1303,7 +1311,7 @@ static inline gboolean client_pipe_add(RedChannelClient *rcc, RedPipeItem *item, void red_channel_client_pipe_add(RedChannelClient *rcc, RedPipeItem *item) { - client_pipe_add(rcc, item, &rcc->pipe); + client_pipe_add(rcc, item, &rcc->priv->pipe); } void red_channel_client_pipe_add_push(RedChannelClient *rcc, RedPipeItem *item) @@ -1329,12 +1337,12 @@ int red_channel_client_pipe_item_is_linked(RedChannelClient *rcc, void red_channel_client_pipe_add_tail(RedChannelClient *rcc, RedPipeItem *item) { - client_pipe_add(rcc, item, rcc->pipe.prev); + client_pipe_add(rcc, item, rcc->priv->pipe.prev); } void red_channel_client_pipe_add_tail_and_push(RedChannelClient *rcc, RedPipeItem *item) { - if (client_pipe_add(rcc, item, rcc->pipe.prev)) { + if (client_pipe_add(rcc, item, rcc->priv->pipe.prev)) { red_channel_client_push(rcc); } } @@ -1361,29 +1369,29 @@ void red_channel_client_pipe_add_empty_msg(RedChannelClient *rcc, int msg_type) gboolean red_channel_client_pipe_is_empty(RedChannelClient *rcc) { g_return_val_if_fail(rcc != NULL, TRUE); - return (rcc->pipe_size == 0) && (ring_is_empty(&rcc->pipe)); + return (rcc->priv->pipe_size == 0) && (ring_is_empty(&rcc->priv->pipe)); } uint32_t red_channel_client_get_pipe_size(RedChannelClient *rcc) { - return rcc->pipe_size; + return rcc->priv->pipe_size; } int red_channel_client_is_connected(RedChannelClient *rcc) { - if (!rcc->dummy) { - return rcc->channel - && (g_list_find(rcc->channel->clients, rcc) != NULL); + if (!rcc->priv->dummy) { + return rcc->priv->channel + && (g_list_find(rcc->priv->channel->clients, rcc) != NULL); } else { - return rcc->dummy_connected; + return rcc->priv->dummy_connected; } } static void red_channel_client_clear_sent_item(RedChannelClient *rcc) { red_channel_client_release_sent_item(rcc); - rcc->send_data.blocked = FALSE; - rcc->send_data.size = 0; + rcc->priv->send_data.blocked = FALSE; + rcc->priv->send_data.size = 0; } static void red_channel_client_pipe_clear(RedChannelClient *rcc) @@ -1393,21 +1401,21 @@ static void red_channel_client_pipe_clear(RedChannelClient *rcc) if (rcc) { red_channel_client_clear_sent_item(rcc); } - while ((item = (RedPipeItem *)ring_get_head(&rcc->pipe))) { + while ((item = (RedPipeItem *)ring_get_head(&rcc->priv->pipe))) { ring_remove(&item->link); red_pipe_item_unref(item); } - rcc->pipe_size = 0; + rcc->priv->pipe_size = 0; } void red_channel_client_ack_zero_messages_window(RedChannelClient *rcc) { - rcc->ack_data.messages_window = 0; + rcc->priv->ack_data.messages_window = 0; } void red_channel_client_ack_set_client_window(RedChannelClient *rcc, int client_window) { - rcc->ack_data.client_window = client_window; + rcc->priv->ack_data.client_window = client_window; } void red_channel_client_push_set_ack(RedChannelClient *rcc) @@ -1419,20 +1427,20 @@ static void red_channel_client_disconnect_dummy(RedChannelClient *rcc) { RedChannel *channel = red_channel_client_get_channel(rcc); GList *link; - spice_assert(rcc->dummy); + spice_assert(rcc->priv->dummy); if (channel && (link = g_list_find(channel->clients, rcc))) { spice_printerr("rcc=%p (channel=%p type=%d id=%d)", rcc, channel, channel->type, channel->id); red_channel_remove_client(channel, link->data); } - rcc->dummy_connected = FALSE; + rcc->priv->dummy_connected = FALSE; } void red_channel_client_disconnect(RedChannelClient *rcc) { - RedChannel *channel = rcc->channel; + RedChannel *channel = rcc->priv->channel; - if (rcc->dummy) { + if (rcc->priv->dummy) { red_channel_client_disconnect_dummy(rcc); return; } @@ -1442,17 +1450,17 @@ void red_channel_client_disconnect(RedChannelClient *rcc) spice_printerr("rcc=%p (channel=%p type=%d id=%d)", rcc, channel, channel->type, channel->id); red_channel_client_pipe_clear(rcc); - if (rcc->stream->watch) { - channel->core->watch_remove(rcc->stream->watch); - rcc->stream->watch = NULL; + if (rcc->priv->stream->watch) { + channel->core->watch_remove(rcc->priv->stream->watch); + rcc->priv->stream->watch = NULL; } - if (rcc->latency_monitor.timer) { - channel->core->timer_remove(rcc->latency_monitor.timer); - rcc->latency_monitor.timer = NULL; + if (rcc->priv->latency_monitor.timer) { + channel->core->timer_remove(rcc->priv->latency_monitor.timer); + rcc->priv->latency_monitor.timer = NULL; } - if (rcc->connectivity_monitor.timer) { - channel->core->timer_remove(rcc->connectivity_monitor.timer); - rcc->connectivity_monitor.timer = NULL; + if (rcc->priv->connectivity_monitor.timer) { + channel->core->timer_remove(rcc->priv->connectivity_monitor.timer); + rcc->priv->connectivity_monitor.timer = NULL; } red_channel_remove_client(channel, rcc); channel->channel_cbs.on_disconnect(rcc); @@ -1460,32 +1468,32 @@ void red_channel_client_disconnect(RedChannelClient *rcc) int red_channel_client_is_blocked(RedChannelClient *rcc) { - return rcc && rcc->send_data.blocked; + return rcc && rcc->priv->send_data.blocked; } int red_channel_client_send_message_pending(RedChannelClient *rcc) { - return rcc->send_data.header.get_msg_type(&rcc->send_data.header) != 0; + return rcc->priv->send_data.header.get_msg_type(&rcc->priv->send_data.header) != 0; } SpiceMarshaller *red_channel_client_get_marshaller(RedChannelClient *rcc) { - return rcc->send_data.marshaller; + return rcc->priv->send_data.marshaller; } RedsStream *red_channel_client_get_stream(RedChannelClient *rcc) { - return rcc->stream; + return rcc->priv->stream; } RedClient *red_channel_client_get_client(RedChannelClient *rcc) { - return rcc->client; + return rcc->priv->client; } void red_channel_client_set_header_sub_list(RedChannelClient *rcc, uint32_t sub_list) { - rcc->send_data.header.set_msg_sub_list(&rcc->send_data.header, sub_list); + rcc->priv->send_data.header.set_msg_sub_list(&rcc->priv->send_data.header, sub_list); } static void marker_pipe_item_free(RedPipeItem *base) @@ -1581,7 +1589,7 @@ int red_channel_client_wait_outgoing_item(RedChannelClient *rcc, void red_channel_client_disconnect_if_pending_send(RedChannelClient *rcc) { - if (red_channel_client_is_blocked(rcc) || rcc->pipe_size > 0) { + if (red_channel_client_is_blocked(rcc) || rcc->priv->pipe_size > 0) { red_channel_client_disconnect(rcc); } else { spice_assert(red_channel_client_no_item_being_sent(rcc)); @@ -1590,7 +1598,7 @@ void red_channel_client_disconnect_if_pending_send(RedChannelClient *rcc) gboolean red_channel_client_no_item_being_sent(RedChannelClient *rcc) { - return !rcc || (rcc->send_data.size == 0); + return !rcc || (rcc->priv->send_data.size == 0); } void red_channel_client_pipe_remove_and_release(RedChannelClient *rcc, @@ -1605,22 +1613,23 @@ gboolean red_channel_client_set_migration_seamless(RedChannelClient *rcc) { gboolean ret = FALSE; - if (rcc->channel->migration_flags & SPICE_MIGRATE_NEED_DATA_TRANSFER) { - rcc->wait_migrate_data = TRUE; + if (rcc->priv->channel->migration_flags & SPICE_MIGRATE_NEED_DATA_TRANSFER) { + rcc->priv->wait_migrate_data = TRUE; ret = TRUE; } - spice_debug("channel type %d id %d rcc %p wait data %d", rcc->channel->type, rcc->channel->id, rcc, - rcc->wait_migrate_data); + spice_debug("channel type %d id %d rcc %p wait data %d", rcc->priv->channel->type, + rcc->priv->channel->id, rcc, + rcc->priv->wait_migrate_data); return ret; } void red_channel_client_set_destroying(RedChannelClient *rcc) { - rcc->destroying = TRUE; + rcc->priv->destroying = TRUE; } gboolean red_channel_client_is_destroying(RedChannelClient *rcc) { - return rcc->destroying; + return rcc->priv->destroying; } diff --git a/server/smartcard.c b/server/smartcard.c index 4bb0b05..504e3c3 100644 --- a/server/smartcard.c +++ b/server/smartcard.c @@ -177,8 +177,8 @@ static void smartcard_send_msg_to_client(RedPipeItem *msg, void *opaque) { RedCharDeviceSmartcard *dev = opaque; - - spice_assert(dev->priv->scc && dev->priv->scc->base.client == client); + RedClient *this_client = red_channel_client_get_client(RED_CHANNEL_CLIENT(dev->priv->scc)); + spice_assert(dev->priv->scc && this_client == client); red_pipe_item_ref(msg); smartcard_channel_client_pipe_add_push(&dev->priv->scc->base, msg); } @@ -191,9 +191,10 @@ static void smartcard_send_tokens_to_client(RedClient *client, uint32_t tokens, static void smartcard_remove_client(RedClient *client, void *opaque) { RedCharDeviceSmartcard *dev = opaque; + RedClient *this_client = red_channel_client_get_client(RED_CHANNEL_CLIENT(dev->priv->scc)); spice_printerr("smartcard dev %p, client %p", dev, client); - spice_assert(dev->priv->scc && dev->priv->scc->base.client == client); + spice_assert(dev->priv->scc && this_client == client); red_channel_client_shutdown(&dev->priv->scc->base); } @@ -324,7 +325,7 @@ static void smartcard_char_device_attach_client(SpiceCharDeviceInstance *char_de dev->priv->scc = scc; scc->priv->smartcard = dev; client_added = red_char_device_client_add(RED_CHAR_DEVICE(dev), - scc->base.client, + red_channel_client_get_client(RED_CHANNEL_CLIENT(scc)), FALSE, /* no flow control yet */ 0, /* send queue size */ ~0, @@ -370,7 +371,8 @@ static void smartcard_char_device_detach_client(SmartCardChannelClient *scc) } dev = scc->priv->smartcard; spice_assert(dev->priv->scc == scc); - red_char_device_client_remove(RED_CHAR_DEVICE(dev), scc->base.client); + red_char_device_client_remove(RED_CHAR_DEVICE(dev), + red_channel_client_get_client(RED_CHANNEL_CLIENT(scc))); scc->priv->smartcard = NULL; dev->priv->scc = NULL; } @@ -385,6 +387,7 @@ static uint8_t *smartcard_channel_alloc_msg_rcv_buf(RedChannelClient *rcc, uint32_t size) { SmartCardChannelClient *scc = SPICE_CONTAINEROF(rcc, SmartCardChannelClient, base); + RedClient *client = red_channel_client_get_client(rcc); /* todo: only one reader is actually supported. When we fix the code to support * multiple readers, we will porbably associate different devices to @@ -399,7 +402,9 @@ static uint8_t *smartcard_channel_alloc_msg_rcv_buf(RedChannelClient *rcc, dev = scc->priv->smartcard; spice_assert(dev->priv->scc || scc->priv->smartcard); spice_assert(!scc->priv->write_buf); - scc->priv->write_buf = red_char_device_write_buffer_get(RED_CHAR_DEVICE(dev), rcc->client, size); + scc->priv->write_buf = + red_char_device_write_buffer_get(RED_CHAR_DEVICE(dev), client, + size); if (!scc->priv->write_buf) { spice_error("failed to allocate write buffer"); diff --git a/server/sound.c b/server/sound.c index 279c927..7f1a2b5 100644 --- a/server/sound.c +++ b/server/sound.c @@ -34,6 +34,7 @@ #include "main-channel.h" #include "reds.h" #include "red-qxl.h" +/* FIXME: for now, allow sound channel access to private RedChannelClient data */ #include "red-channel-client-private.h" #include "sound.h" #include <common/snd_codec.h> @@ -523,7 +524,7 @@ static inline int snd_reset_send_data(SndChannel *channel, uint16_t verb) return FALSE; } - header = &channel->channel_client->send_data.header; + header = &channel->channel_client->priv->send_data.header; spice_marshaller_reset(channel->send_data.marshaller); header->data = spice_marshaller_reserve_space(channel->send_data.marshaller, header->header_size); @@ -533,7 +534,7 @@ static inline int snd_reset_send_data(SndChannel *channel, uint16_t verb) header->set_msg_size(header, 0); header->set_msg_type(header, verb); channel->send_data.serial++; - if (!channel->channel_client->is_mini_header) { + if (!channel->channel_client->priv->is_mini_header) { header->set_msg_serial(header, channel->send_data.serial); header->set_msg_sub_list(header, 0); } @@ -543,7 +544,7 @@ static inline int snd_reset_send_data(SndChannel *channel, uint16_t verb) static int snd_begin_send_message(SndChannel *channel) { - SpiceDataHeaderOpaque *header = &channel->channel_client->send_data.header; + SpiceDataHeaderOpaque *header = &channel->channel_client->priv->send_data.header; spice_marshaller_flush(channel->send_data.marshaller); channel->send_data.size = spice_marshaller_get_total_size(channel->send_data.marshaller); @@ -996,12 +997,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); @@ -1144,7 +1146,7 @@ void snd_set_playback_latency(RedClient *client, uint32_t latency) for (; now; now = now->next) { if (now->base_channel->type == SPICE_CHANNEL_PLAYBACK && now->connection && - now->connection->channel_client->client == client) { + red_channel_client_get_client(now->connection->channel_client) == client) { if (red_channel_client_test_remote_cap(now->connection->channel_client, SPICE_PLAYBACK_CAP_LATENCY)) { @@ -1265,11 +1267,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); @@ -1494,10 +1497,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 9e34251..d09a0c7 100644 --- a/server/spicevmc.c +++ b/server/spicevmc.c @@ -129,7 +129,7 @@ static RedVmcPipeItem* try_compress_lz4(SpiceVmcState *state, int n, RedVmcPipeI RedVmcPipeItem *msg_item_compressed; int compressed_data_count; - if (reds_stream_get_family(state->rcc->stream) == AF_UNIX) { + if (reds_stream_get_family(state->rcc->priv->stream) == AF_UNIX) { /* AF_LOCAL - data will not be compressed */ return NULL; } @@ -353,7 +353,7 @@ static int handle_compressed_msg(SpiceVmcState *state, RedChannelClient *rcc, int decompressed_size; RedCharDeviceWriteBuffer *write_buf; - write_buf = red_char_device_write_buffer_get(state->chardev, rcc->client, + write_buf = red_char_device_write_buffer_get(state->chardev, rcc->priv->client, compressed_data_msg->uncompressed_size); if (!write_buf) { return FALSE; -- 2.7.4 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel