[Spice-devel] [PATCH v2 07/10] Add RedChannelClientPrivate struct
Jonathon Jongsma
jjongsma at redhat.com
Wed Sep 7 20:37:25 UTC 2016
Encapsulate private data and prepare for port to GObject
---
Changes in v2:
- Fixed leak of priv by using 1-element array trick
- moved unrelated change
- added red_channel_client_get_pipe() and red_channel_client_is_mini_header()
to avoid accessing RedChannelClientPrivate from DisplayChannelClient.
server/Makefile.am | 1 +
server/dcc-send.c | 11 +-
server/dcc.c | 7 +-
server/red-channel-client-private.h | 76 +++++
server/red-channel-client.c | 578 +++++++++++++++++++-----------------
server/red-channel-client.h | 55 +---
server/sound.c | 8 +-
7 files changed, 397 insertions(+), 339 deletions(-)
create mode 100644 server/red-channel-client-private.h
diff --git a/server/Makefile.am b/server/Makefile.am
index 09939f3..9c5b3b6 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/dcc-send.c b/server/dcc-send.c
index 999b44b..7c9f4e1 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,7 @@ 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_get_pipe(RED_CHANNEL_CLIENT(dcc)));
}
static void red_display_add_image_to_pixmap_cache(RedChannelClient *rcc,
@@ -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(red_channel_client_get_stream(rcc)) == 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_get_pipe(RED_CHANNEL_CLIENT(dcc));
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_get_pipe(RED_CHANNEL_CLIENT(dcc));
// going from the oldest to the newest
for (pipe_item = (RedPipeItem *)ring_get_tail(pipe);
@@ -2367,7 +2368,7 @@ static void begin_send_message(RedChannelClient *rcc)
}
free_list->wait.header.wait_count = sync_count;
- if (rcc->is_mini_header) {
+ if (red_channel_client_is_mini_header(rcc)) {
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..532bfa3
--- /dev/null
+++ b/server/red-channel-client-private.h
@@ -0,0 +1,76 @@
+/*
+ Copyright (C) 2009-2015 Red Hat, Inc.
+
+ 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.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 b8555ff..0eed02b 100644
--- a/server/red-channel-client.c
+++ b/server/red-channel-client.c
@@ -34,6 +34,7 @@
#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 +66,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,25 +104,25 @@ 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;
}
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;
}
}
@@ -129,7 +130,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,
@@ -137,7 +138,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);
}
@@ -145,46 +146,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);
}
}
@@ -194,11 +195,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);
}
@@ -208,10 +209,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);
@@ -221,25 +222,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 measurement 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));
@@ -250,9 +251,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);
}
@@ -284,7 +285,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);
@@ -292,21 +293,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)
@@ -314,10 +316,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)
@@ -329,18 +331,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);
}
@@ -350,7 +354,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);
}
@@ -358,41 +362,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);
}
@@ -401,7 +407,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. */
@@ -409,7 +415,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) {
@@ -427,8 +433,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));
}
/*
@@ -446,12 +452,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");
@@ -459,8 +465,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");
@@ -471,20 +477,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);
}
}
@@ -502,22 +508,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);
}
}
}
@@ -636,18 +642,18 @@ 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->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;
@@ -660,12 +666,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;
@@ -675,26 +681,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;
@@ -720,27 +726,27 @@ 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->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);
@@ -752,79 +758,79 @@ error:
static 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);
@@ -832,11 +838,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;
}
}
@@ -1020,14 +1026,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);
}
@@ -1035,9 +1041,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);
@@ -1048,44 +1054,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);
}
@@ -1095,27 +1101,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));
@@ -1129,14 +1135,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);
}
@@ -1190,23 +1196,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_client_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_client_handle_migrate_data(rcc, size, message);
@@ -1225,8 +1231,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);
}
@@ -1234,10 +1240,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;
}
@@ -1246,37 +1252,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)
@@ -1287,12 +1294,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;
}
@@ -1300,7 +1307,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)
@@ -1326,12 +1333,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);
}
}
@@ -1358,29 +1365,39 @@ 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;
+}
+
+Ring* red_channel_client_get_pipe(RedChannelClient *rcc)
+{
+ return &rcc->priv->pipe;
+}
+
+gboolean red_channel_client_is_mini_header(RedChannelClient *rcc)
+{
+ return rcc->priv->is_mini_header;
}
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;
}
// TODO: again - what is the context exactly? this happens in channel disconnect. but our
@@ -1393,21 +1410,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 +1436,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 +1459,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 +1477,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 +1598,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 +1607,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 +1622,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 bef052b..d2f7b3e 100644
--- a/server/red-channel-client.h
+++ b/server/red-channel-client.h
@@ -23,12 +23,15 @@
#include "red-pipe-item.h"
#include "reds-stream.h"
#include "red-channel.h"
+/* FIXME: remove */
+#include "red-channel-client-private.h"
typedef struct RedChannel RedChannel;
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
@@ -111,6 +114,8 @@ void red_channel_client_pipe_add_type(RedChannelClient *rcc, int pipe_item_type)
void red_channel_client_pipe_add_empty_msg(RedChannelClient *rcc, int msg_type);
gboolean red_channel_client_pipe_is_empty(RedChannelClient *rcc);
uint32_t red_channel_client_get_pipe_size(RedChannelClient *rcc);
+Ring* red_channel_client_get_pipe(RedChannelClient *rcc);
+gboolean red_channel_client_is_mini_header(RedChannelClient *rcc);
void red_channel_client_ack_zero_messages_window(RedChannelClient *rcc);
void red_channel_client_ack_set_client_window(RedChannelClient *rcc, int client_window);
@@ -192,57 +197,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[1];
};
#endif /* _H_RED_CHANNEL_CLIENT */
diff --git a/server/sound.c b/server/sound.c
index 52fe1c3..c08bb35 100644
--- a/server/sound.c
+++ b/server/sound.c
@@ -35,6 +35,8 @@
#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 +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);
@@ -532,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);
}
@@ -542,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);
--
2.7.4
More information about the Spice-devel
mailing list