[Spice-devel] [PATCH 08/10] Add RedChannelClientPrivate struct

Victor Toso lists at victortoso.com
Thu Sep 1 10:15:35 UTC 2016


Hi,

On Wed, Aug 31, 2016 at 11:54:44AM -0500, Jonathon Jongsma wrote:
> Encapsulate private data and prepare for port to GObject
> ---
>  server/Makefile.am                  |   1 +
>  server/cursor-channel.c             |   3 +-
>  server/dcc-send.c                   |  12 +-
>  server/dcc.c                        |   7 +-
>  server/red-channel-client-private.h |  77 +++++
>  server/red-channel-client.c         | 571 ++++++++++++++++++------------------
>  server/red-channel-client.h         |  51 +---
>  server/sound.c                      |   9 +-
>  8 files changed, 389 insertions(+), 342 deletions(-)
>  create mode 100644 server/red-channel-client-private.h
> 
> diff --git a/server/Makefile.am b/server/Makefile.am
> index 771b33f..900e862 100644
> --- a/server/Makefile.am
> +++ b/server/Makefile.am
> @@ -99,6 +99,7 @@ libserver_la_SOURCES =				\
>  	red-channel.h				\
>  	red-channel-client.c			\
>  	red-channel-client.h			\
> +	red-channel-client-private.h		\
>  	red-common.h				\
>  	dispatcher.c				\
>  	dispatcher.h				\
> diff --git a/server/cursor-channel.c b/server/cursor-channel.c
> index bf778dd..982c308 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);

Unrelated change. Should go to patch 03 "Move CursorChannelClient to
separate file"

>      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 999b44b..032fb0f 100644
> --- a/server/dcc-send.c
> +++ b/server/dcc-send.c
> @@ -21,6 +21,7 @@
>
>  #include "dcc-private.h"
>  #include "display-channel.h"
> +#include "red-channel-client-private.h"
>
>  #include <common/marshaller.h>
>  #include <common/generated_server_marshallers.h>
> @@ -188,7 +189,8 @@ 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);
> +    /* FIXME: don't poke rcc private */
> +    return (RedPipeItem*)ring_get_tail(&RED_CHANNEL_CLIENT(dcc)->priv->pipe);

If I got this right, changing dcc_add_surface_area_image to use
red_channel_client_pipe_add_tail() would be enough to get rid of
dcc_get_tail

>  }
>
>  static void red_display_add_image_to_pixmap_cache(RedChannelClient *rcc,
> @@ -441,7 +443,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 ||

use red_channel_client_get_stream() instead? or like dcc is doing in
this patch:
  reds_stream_is_plain_unix(red_channel_client_get_stream(rcc))

>              !dcc_compress_image(dcc, &image, &simage->u.bitmap,
>                                  drawable, can_lossy, &comp_send_data)) {
>              SpicePalette *palette;
> @@ -620,7 +622,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;

We might include some _get_pipe() instead?

>
>      for (pipe_item = (RedPipeItem *)ring_get_head(pipe);
>           pipe_item;
> @@ -712,7 +714,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);
> @@ -2367,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) {

_is_mini_header as function?

If those two functions make sense, dcc.c and dcc-send.c would not access
rcc->priv directly at least.

>              send_free_list(rcc);
>          } else {
>              send_free_list_legacy(rcc);
> diff --git a/server/dcc.c b/server/dcc.c
> index 8eca28b..87ef145 100644
> --- a/server/dcc.c
> +++ b/server/dcc.c
> @@ -21,6 +21,7 @@
>
>  #include "dcc-private.h"
>  #include "display-channel.h"
> +#include "red-channel-client-private.h"
>
>  #define DISPLAY_CLIENT_SHORT_TIMEOUT 15000000000ULL //nano
>
> @@ -76,7 +77,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;
> @@ -459,7 +460,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);
> @@ -573,7 +574,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);
> diff --git a/server/red-channel-client-private.h b/server/red-channel-client-private.h
> new file mode 100644
> index 0000000..acaf2a7
> --- /dev/null
> +++ b/server/red-channel-client-private.h
> @@ -0,0 +1,77 @@
> +/*
> +    Copyright (C) 2009-2015 Red Hat, Inc.

-2016

> +
> +   This library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   This library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with this library; if not, see <http://www.gnu.org/licenses/>.
> +*/
> +
> +#ifndef _H_RED_CHANNEL_CLIENT_PRIVATE
> +#define _H_RED_CHANNEL_CLIENT_PRIVATE
> +
> +#include "red-channel-client.h"
> +#include "red-channel.h"
> +
> +struct RedChannelClientPrivate
> +{
> +    RedChannel *channel;
> +    RedClient  *client;
> +    RedsStream *stream;
> +    int dummy;
> +    int dummy_connected;
> +
> +    uint32_t refs;
> +
> +    struct {
> +        uint32_t generation;
> +        uint32_t client_generation;
> +        uint32_t messages_window;
> +        uint32_t client_window;
> +    } ack_data;
> +
> +    struct {
> +        SpiceMarshaller *marshaller;
> +        SpiceDataHeaderOpaque header;
> +        uint32_t size;
> +        RedPipeItem *item;
> +        int blocked;
> +        uint64_t serial;
> +        uint64_t last_sent_serial;
> +
> +        struct {
> +            SpiceMarshaller *marshaller;
> +            uint8_t *header_data;
> +            RedPipeItem *item;
> +        } main;
> +
> +        struct {
> +            SpiceMarshaller *marshaller;
> +        } urgent;
> +    } send_data;
> +
> +    int during_send;
> +    int id; // debugging purposes
> +    Ring pipe;
> +    uint32_t pipe_size;
> +
> +    RedChannelCapabilities remote_caps;
> +    int is_mini_header;
> +    gboolean destroying;
> +
> +    int wait_migrate_data;
> +    int wait_migrate_flush_mark;
> +
> +    RedChannelClientLatencyMonitor latency_monitor;
> +    RedChannelClientConnectivityMonitor connectivity_monitor;
> +};
> +
> +#endif /* _H_RED_CHANNEL_CLIENT_PRIVATE */
> diff --git a/server/red-channel-client.c b/server/red-channel-client.c
> index 253e30e..82afac8 100644
> --- a/server/red-channel-client.c
> +++ b/server/red-channel-client.c
> @@ -33,7 +33,7 @@
>  #endif
>  #include <common/generated_server_marshallers.h>
>  
> -#include "red-channel-client.h"
> +#include "red-channel-client-private.h"
>  #include "red-channel.h"
>  
>  #define PING_TEST_TIMEOUT_MS (MSEC_PER_SEC * 15)
> @@ -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);

/* FIXME will leak */

Reviewed-by: Victor Toso <victortoso at redhat.com>

> +    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/red-channel-client.h b/server/red-channel-client.h
> index bacfeb5..a6c1146 100644
> --- a/server/red-channel-client.h
> +++ b/server/red-channel-client.h
> @@ -29,6 +29,7 @@ typedef struct RedClient RedClient;
>  typedef struct IncomingHandler IncomingHandler;
>  
>  typedef struct RedChannelClient RedChannelClient;
> +typedef struct RedChannelClientPrivate RedChannelClientPrivate;
>  
>  /*
>   * When an error occurs over a channel, we treat it as a warning
> @@ -197,57 +198,11 @@ typedef struct IncomingHandler {
>  } IncomingHandler;
>  
>  struct RedChannelClient {
> -    RedChannel *channel;
> -    RedClient  *client;
> -    RedsStream *stream;
> -    int dummy;
> -    int dummy_connected;
> -
> -    uint32_t refs;
> -
> -    struct {
> -        uint32_t generation;
> -        uint32_t client_generation;
> -        uint32_t messages_window;
> -        uint32_t client_window;
> -    } ack_data;
> -
> -    struct {
> -        SpiceMarshaller *marshaller;
> -        SpiceDataHeaderOpaque header;
> -        uint32_t size;
> -        RedPipeItem *item;
> -        int blocked;
> -        uint64_t serial;
> -        uint64_t last_sent_serial;
> -
> -        struct {
> -            SpiceMarshaller *marshaller;
> -            uint8_t *header_data;
> -            RedPipeItem *item;
> -        } main;
> -
> -        struct {
> -            SpiceMarshaller *marshaller;
> -        } urgent;
> -    } send_data;
> -
> +    /* protected */
>      OutgoingHandler outgoing;
>      IncomingHandler incoming;
> -    int during_send;
> -    int id; // debugging purposes
> -    Ring pipe;
> -    uint32_t pipe_size;
> -
> -    RedChannelCapabilities remote_caps;
> -    int is_mini_header;
> -    gboolean destroying;
> -
> -    int wait_migrate_data;
> -    int wait_migrate_flush_mark;
>  
> -    RedChannelClientLatencyMonitor latency_monitor;
> -    RedChannelClientConnectivityMonitor connectivity_monitor;
> +    RedChannelClientPrivate *priv;
>  };
>  
>  #endif /* _H_RED_CHANNEL_CLIENT */
> diff --git a/server/sound.c b/server/sound.c
> index 52fe1c3..30b1472 100644
> --- a/server/sound.c
> +++ b/server/sound.c
> @@ -34,7 +34,8 @@
>  #include "main-channel.h"
>  #include "reds.h"
>  #include "red-qxl.h"
> -#include "red-channel-client.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>
>  #include "demarshallers.h"
> @@ -522,7 +523,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);
> @@ -532,7 +533,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);
>      }
> @@ -542,7 +543,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);
> -- 
> 2.7.4
> 
> _______________________________________________
> Spice-devel mailing list
> Spice-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/spice-devel


More information about the Spice-devel mailing list