summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathon Jongsma <jjongsma@redhat.com>2015-10-01 10:39:18 -0500
committerJonathon Jongsma <jjongsma@redhat.com>2016-09-01 17:42:59 -0500
commit2f5d1f575929f36ea7a549d4a5feffbd2952a725 (patch)
tree3eee327c5cf1c998d4ab8ce5f20d5aeaa5d01e54
parentb97688634b674a6846e50764c069b70207baa39a (diff)
fb94cb76efab57dfc27c6755d95b945181a7b42d RedChannelClient: store pipe items in a GList
Instead of using a Ring (and having a ring item link in every pipe item), store them in a GList. This also necesitated changing RedCharDeviceVDIPort->priv->read_bufs to a GList as well.
-rw-r--r--server/cursor-channel.c2
-rw-r--r--server/dcc-send.c23
-rw-r--r--server/dcc.c22
-rw-r--r--server/display-channel.c7
-rw-r--r--server/red-channel-client-private.h3
-rw-r--r--server/red-channel-client.c69
-rw-r--r--server/red-pipe-item.c1
-rw-r--r--server/red-pipe-item.h6
-rw-r--r--server/reds.c14
-rw-r--r--server/stream.c3
10 files changed, 72 insertions, 78 deletions
diff --git a/server/cursor-channel.c b/server/cursor-channel.c
index a9a29784..3dcc7349 100644
--- a/server/cursor-channel.c
+++ b/server/cursor-channel.c
@@ -188,8 +188,6 @@ static void cursor_pipe_item_free(RedPipeItem *base)
RedCursorPipeItem *pipe_item = SPICE_UPCAST(RedCursorPipeItem, base);
- spice_assert(!red_pipe_item_is_linked(&pipe_item->base));
-
cursor_item_unref(pipe_item->cursor_item);
free(pipe_item);
}
diff --git a/server/dcc-send.c b/server/dcc-send.c
index 4e789f1d..b4be511b 100644
--- a/server/dcc-send.c
+++ b/server/dcc-send.c
@@ -190,7 +190,8 @@ static int is_brush_lossy(RedChannelClient *rcc, SpiceBrush *brush,
static RedPipeItem *dcc_get_tail(DisplayChannelClient *dcc)
{
/* FIXME: don't poke rcc private */
- return (RedPipeItem*)ring_get_tail(&RED_CHANNEL_CLIENT(dcc)->priv->pipe);
+ GList *last = g_list_last(RED_CHANNEL_CLIENT(dcc)->priv->pipe);
+ return last->data;
}
static void red_display_add_image_to_pixmap_cache(RedChannelClient *rcc,
@@ -619,17 +620,13 @@ static int pipe_rendered_drawables_intersect_with_areas(DisplayChannelClient *dc
SpiceRect *surface_areas[],
int num_surfaces)
{
- RedPipeItem *pipe_item;
- Ring *pipe;
+ GList *l;
spice_assert(num_surfaces);
- pipe = &RED_CHANNEL_CLIENT(dcc)->priv->pipe;
- for (pipe_item = (RedPipeItem *)ring_get_head(pipe);
- pipe_item;
- pipe_item = (RedPipeItem *)ring_next(pipe, &pipe_item->link))
- {
+ for (l = RED_CHANNEL_CLIENT(dcc)->priv->pipe; l != NULL; l = l->next) {
Drawable *drawable;
+ RedPipeItem *pipe_item = l->data;
if (pipe_item->type != RED_PIPE_ITEM_TYPE_DRAW)
continue;
@@ -708,19 +705,15 @@ static void red_pipe_replace_rendered_drawables_with_images(DisplayChannelClient
int resent_surface_ids[MAX_PIPE_SIZE];
SpiceRect resent_areas[MAX_PIPE_SIZE]; // not pointers since drawables may be released
int num_resent;
- RedPipeItem *pipe_item;
- Ring *pipe;
+ GList *l;
resent_surface_ids[0] = first_surface_id;
resent_areas[0] = *first_area;
num_resent = 1;
- pipe = &RED_CHANNEL_CLIENT(dcc)->priv->pipe;
-
// going from the oldest to the newest
- for (pipe_item = (RedPipeItem *)ring_get_tail(pipe);
- pipe_item;
- pipe_item = (RedPipeItem *)ring_prev(pipe, &pipe_item->link)) {
+ for (l = g_list_last(RED_CHANNEL_CLIENT(dcc)->priv->pipe); l != NULL; l = l->prev) {
+ RedPipeItem *pipe_item = l->data;
Drawable *drawable;
RedDrawablePipeItem *dpi;
RedImageItem *image;
diff --git a/server/dcc.c b/server/dcc.c
index bfc9fc32..e582e3bb 100644
--- a/server/dcc.c
+++ b/server/dcc.c
@@ -216,8 +216,8 @@ int dcc_drawable_is_in_pipe(DisplayChannelClient *dcc, Drawable *drawable)
int dcc_clear_surface_drawables_from_pipe(DisplayChannelClient *dcc, int surface_id,
int wait_if_used)
{
- Ring *ring;
- RedPipeItem *item;
+ GList *l;
+ RedPipeItem *item = NULL;
int x;
RedChannelClient *rcc;
@@ -226,13 +226,15 @@ int dcc_clear_surface_drawables_from_pipe(DisplayChannelClient *dcc, int surface
no other drawable depends on them */
rcc = RED_CHANNEL_CLIENT(dcc);
- ring = &rcc->priv->pipe;
- item = (RedPipeItem *) ring;
- while ((item = (RedPipeItem *)ring_next(ring, &item->link))) {
+ l = rcc->priv->pipe;
+ while (l != NULL) {
+ GList *cur = l;
Drawable *drawable;
RedDrawablePipeItem *dpi = NULL;
int depend_found = FALSE;
+ l = l->next;
+ item = cur->data;
if (item->type == RED_PIPE_ITEM_TYPE_DRAW) {
dpi = SPICE_CONTAINEROF(item, RedDrawablePipeItem, dpi_pipe_item);
drawable = dpi->drawable;
@@ -243,12 +245,7 @@ int dcc_clear_surface_drawables_from_pipe(DisplayChannelClient *dcc, int surface
}
if (drawable->surface_id == surface_id) {
- RedPipeItem *tmp_item = item;
- item = (RedPipeItem *)ring_prev(ring, &item->link);
- red_channel_client_pipe_remove_and_release(rcc, tmp_item);
- if (!item) {
- item = (RedPipeItem *)ring;
- }
+ red_channel_client_pipe_remove_and_release(rcc, item);
continue;
}
@@ -437,7 +434,8 @@ static void red_drawable_pipe_item_free(RedPipeItem *item)
dpi_pipe_item);
spice_assert(item->refcount == 0);
- spice_warn_if_fail(!ring_item_is_linked(&item->link));
+ spice_warn_if_fail(!red_channel_client_pipe_item_is_linked(RED_CHANNEL_CLIENT(dpi->dcc),
+ &dpi->dpi_pipe_item));
if (ring_item_is_linked(&dpi->base)) {
ring_remove(&dpi->base);
}
diff --git a/server/display-channel.c b/server/display-channel.c
index e28f61bc..e378b9c2 100644
--- a/server/display-channel.c
+++ b/server/display-channel.c
@@ -471,9 +471,12 @@ static void drawable_remove_from_pipes(Drawable *drawable)
RingItem *item, *next;
RING_FOREACH_SAFE(item, next, &drawable->pipes) {
+ RedChannelClient *rcc;
+
dpi = SPICE_UPCAST(RedDrawablePipeItem, item);
- if (red_pipe_item_is_linked(&dpi->dpi_pipe_item)) {
- red_channel_client_pipe_remove_and_release(RED_CHANNEL_CLIENT(dpi->dcc),
+ rcc = RED_CHANNEL_CLIENT(dpi->dcc);
+ if (red_channel_client_pipe_item_is_linked(rcc, &dpi->dpi_pipe_item)) {
+ red_channel_client_pipe_remove_and_release(rcc,
&dpi->dpi_pipe_item);
}
}
diff --git a/server/red-channel-client-private.h b/server/red-channel-client-private.h
index adf9f2f3..ea7603ed 100644
--- a/server/red-channel-client-private.h
+++ b/server/red-channel-client-private.h
@@ -78,8 +78,7 @@ struct RedChannelClientPrivate
int during_send;
int id; // debugging purposes
- Ring pipe;
- uint32_t pipe_size;
+ GList *pipe;
RedChannelCapabilities remote_caps;
int is_mini_header;
diff --git a/server/red-channel-client.c b/server/red-channel-client.c
index 652743a7..5a64a425 100644
--- a/server/red-channel-client.c
+++ b/server/red-channel-client.c
@@ -429,9 +429,6 @@ red_channel_client_init(RedChannelClient *self)
self->priv->send_data.urgent.marshaller = spice_marshaller_new();
self->priv->send_data.marshaller = self->priv->send_data.main.marshaller;
-
- ring_init(&self->priv->pipe);
- self->priv->pipe_size = 0;
}
RedChannel* red_channel_client_get_channel(RedChannelClient* rcc)
@@ -678,7 +675,7 @@ void red_channel_client_on_out_msg_done(void *opaque)
} else {
if (rcc->priv->latency_monitor.timer
&& !rcc->priv->send_data.blocked
- && rcc->priv->pipe_size == 0) {
+ && rcc->priv->pipe == NULL) {
/* It is possible that the socket will become idle, so we may be able to test latency */
red_channel_client_restart_ping_timer(rcc);
}
@@ -688,8 +685,7 @@ void red_channel_client_on_out_msg_done(void *opaque)
static void red_channel_client_pipe_remove(RedChannelClient *rcc, RedPipeItem *item)
{
- rcc->priv->pipe_size--;
- ring_remove(&item->link);
+ rcc->priv->pipe = g_list_remove(rcc->priv->pipe, item);
}
int red_channel_client_test_remote_common_cap(RedChannelClient *rcc, uint32_t cap)
@@ -1214,14 +1210,16 @@ void red_channel_client_send(RedChannelClient *rcc)
static inline RedPipeItem *red_channel_client_pipe_item_get(RedChannelClient *rcc)
{
+ GList *l;
RedPipeItem *item;
if (!rcc || rcc->priv->send_data.blocked
|| red_channel_client_waiting_for_ack(rcc)
- || !(item = (RedPipeItem *)ring_get_tail(&rcc->priv->pipe))) {
+ || !(l = g_list_last(rcc->priv->pipe))) {
return NULL;
}
- red_channel_client_pipe_remove(rcc, item);
+ item = l->data;
+ rcc->priv->pipe = g_list_delete_link(rcc->priv->pipe, l);
return item;
}
@@ -1247,7 +1245,7 @@ void red_channel_client_push(RedChannelClient *rcc)
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->priv->pipe)
+ if (red_channel_client_no_item_being_sent(rcc) && rcc->priv->pipe == NULL
&& rcc->priv->stream->watch) {
SpiceCoreInterfaceInternal *core;
core = red_channel_get_core_interface(rcc->priv->channel);
@@ -1468,7 +1466,7 @@ void red_channel_client_set_message_serial(RedChannelClient *rcc, uint64_t seria
rcc->priv->send_data.serial = serial;
}
-static inline gboolean client_pipe_add(RedChannelClient *rcc, RedPipeItem *item, RingItem *pos)
+static inline gboolean prepare_pipe_add(RedChannelClient *rcc, RedPipeItem *item)
{
spice_assert(rcc && item);
if (SPICE_UNLIKELY(!red_channel_client_is_connected(rcc))) {
@@ -1476,21 +1474,22 @@ static inline gboolean client_pipe_add(RedChannelClient *rcc, RedPipeItem *item,
red_pipe_item_unref(item);
return FALSE;
}
- if (ring_is_empty(&rcc->priv->pipe) && rcc->priv->stream->watch) {
+ if (rcc->priv->pipe == NULL && rcc->priv->stream->watch) {
SpiceCoreInterfaceInternal *core;
core = red_channel_get_core_interface(rcc->priv->channel);
core->watch_update_mask(rcc->priv->stream->watch,
SPICE_WATCH_EVENT_READ | SPICE_WATCH_EVENT_WRITE);
}
- rcc->priv->pipe_size++;
- ring_add(pos, &item->link);
return TRUE;
}
void red_channel_client_pipe_add(RedChannelClient *rcc, RedPipeItem *item)
{
- client_pipe_add(rcc, item, &rcc->priv->pipe);
+ if (!prepare_pipe_add(rcc, item)) {
+ return;
+ }
+ rcc->priv->pipe = g_list_prepend(rcc->priv->pipe, item);
}
void red_channel_client_pipe_add_push(RedChannelClient *rcc, RedPipeItem *item)
@@ -1503,27 +1502,40 @@ void red_channel_client_pipe_add_after(RedChannelClient *rcc,
RedPipeItem *item,
RedPipeItem *pos)
{
+ GList *prev = NULL;
+
spice_assert(pos);
- client_pipe_add(rcc, item, &pos->link);
+ if (!prepare_pipe_add(rcc, item)) {
+ return;
+ }
+ prev = g_list_find(rcc->priv->pipe, pos);
+ g_return_if_fail(prev != NULL);
+
+ rcc->priv->pipe = g_list_insert_before(rcc->priv->pipe, prev->next, item);
}
int red_channel_client_pipe_item_is_linked(RedChannelClient *rcc,
RedPipeItem *item)
{
- return ring_item_is_linked(&item->link);
+ return g_list_find(rcc->priv->pipe, item) != NULL;
}
void red_channel_client_pipe_add_tail(RedChannelClient *rcc,
RedPipeItem *item)
{
- client_pipe_add(rcc, item, rcc->priv->pipe.prev);
+ if (!prepare_pipe_add(rcc, item)) {
+ return;
+ }
+ rcc->priv->pipe = g_list_append(rcc->priv->pipe, item);
}
void red_channel_client_pipe_add_tail_and_push(RedChannelClient *rcc, RedPipeItem *item)
{
- if (client_pipe_add(rcc, item, rcc->priv->pipe.prev)) {
- red_channel_client_push(rcc);
+ if (!prepare_pipe_add(rcc, item)) {
+ return;
}
+ rcc->priv->pipe = g_list_append(rcc->priv->pipe, item);
+ red_channel_client_push(rcc);
}
void red_channel_client_pipe_add_type(RedChannelClient *rcc, int pipe_item_type)
@@ -1548,12 +1560,12 @@ 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->priv->pipe_size == 0) && (ring_is_empty(&rcc->priv->pipe));
+ return (rcc->priv->pipe == NULL);
}
uint32_t red_channel_client_get_pipe_size(RedChannelClient *rcc)
{
- return rcc->priv->pipe_size;
+ return g_list_length(rcc->priv->pipe);
}
static gboolean red_channel_client_default_is_connected(RedChannelClient *rcc)
@@ -1582,16 +1594,15 @@ static void red_channel_client_clear_sent_item(RedChannelClient *rcc)
// are we reading from an fd here? arghh
static void red_channel_client_pipe_clear(RedChannelClient *rcc)
{
- RedPipeItem *item;
+ GList *l;
if (rcc) {
red_channel_client_clear_sent_item(rcc);
}
- while ((item = (RedPipeItem *)ring_get_head(&rcc->priv->pipe))) {
- ring_remove(&item->link);
- red_pipe_item_unref(item);
+ while ((l = rcc->priv->pipe)) {
+ red_pipe_item_unref(l->data);
+ rcc->priv->pipe = g_list_delete_link(rcc->priv->pipe, l);
}
- rcc->priv->pipe_size = 0;
}
void red_channel_client_ack_zero_messages_window(RedChannelClient *rcc)
@@ -1716,8 +1727,8 @@ int red_channel_client_wait_pipe_item_sent(RedChannelClient *rcc,
}
red_channel_client_push(rcc);
- while(item_in_pipe &&
- (timeout == -1 || spice_get_monotonic_time_ns() < end_time)) {
+ while (item_in_pipe &&
+ (timeout == -1 || spice_get_monotonic_time_ns() < end_time)) {
usleep(CHANNEL_BLOCKED_SLEEP_DURATION);
red_channel_client_receive(rcc);
red_channel_client_send(rcc);
@@ -1769,7 +1780,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->priv->pipe_size > 0) {
+ if (red_channel_client_is_blocked(rcc) || rcc->priv->pipe != NULL) {
red_channel_client_disconnect(rcc);
} else {
spice_assert(red_channel_client_no_item_being_sent(rcc));
diff --git a/server/red-pipe-item.c b/server/red-pipe-item.c
index 31262fa9..d8996106 100644
--- a/server/red-pipe-item.c
+++ b/server/red-pipe-item.c
@@ -42,7 +42,6 @@ void red_pipe_item_init_full(RedPipeItem *item,
gint type,
red_pipe_item_free_t *free_func)
{
- ring_item_init(&item->link);
item->type = type;
item->refcount = 1;
item->free_func = free_func ? free_func : (red_pipe_item_free_t *)free;
diff --git a/server/red-pipe-item.h b/server/red-pipe-item.h
index bf13b0be..a589c68a 100644
--- a/server/red-pipe-item.h
+++ b/server/red-pipe-item.h
@@ -26,7 +26,6 @@ struct RedPipeItem;
typedef void red_pipe_item_free_t(struct RedPipeItem *item);
typedef struct RedPipeItem {
- RingItem link;
int type;
/* private */
@@ -39,11 +38,6 @@ void red_pipe_item_init_full(RedPipeItem *item, int type, red_pipe_item_free_t f
RedPipeItem *red_pipe_item_ref(RedPipeItem *item);
void red_pipe_item_unref(RedPipeItem *item);
-static inline int red_pipe_item_is_linked(RedPipeItem *item)
-{
- return ring_item_is_linked(&item->link);
-}
-
static inline void red_pipe_item_init(RedPipeItem *item, int type)
{
red_pipe_item_init_full(item, type, NULL);
diff --git a/server/reds.c b/server/reds.c
index 04c9dfff..e49f0dc1 100644
--- a/server/reds.c
+++ b/server/reds.c
@@ -238,7 +238,7 @@ struct RedCharDeviceVDIPortPrivate {
AgentMsgFilter write_filter;
/* read from agent */
- Ring read_bufs;
+ GList *read_bufs;
uint32_t read_state;
uint32_t message_receive_len;
uint8_t *receive_pos;
@@ -802,15 +802,15 @@ static void vdi_read_buf_init(RedVDIReadBuf *buf)
static RedVDIReadBuf *vdi_port_get_read_buf(RedCharDeviceVDIPort *dev)
{
- RingItem *item;
+ GList *item;
RedVDIReadBuf *buf;
- if (!(item = ring_get_head(&dev->priv->read_bufs))) {
+ if (!(item = g_list_first(dev->priv->read_bufs))) {
return NULL;
}
- ring_remove(item);
- buf = SPICE_CONTAINEROF(item, RedVDIReadBuf, base.link);
+ buf = item->data;
+ dev->priv->read_bufs = g_list_delete_link(dev->priv->read_bufs, item);
g_warn_if_fail(buf->base.refcount == 0);
vdi_read_buf_init(buf);
@@ -823,7 +823,7 @@ static void vdi_port_read_buf_free(RedPipeItem *base)
RedVDIReadBuf *buf = SPICE_UPCAST(RedVDIReadBuf, base);
g_warn_if_fail(buf->base.refcount == 0);
- ring_add(&buf->dev->priv->read_bufs, &buf->base.link);
+ buf->dev->priv->read_bufs = g_list_prepend(buf->dev->priv->read_bufs, buf);
/* read_one_msg_from_vdi_port may have never completed because the read_bufs
ring was empty. So we call it again so it can complete its work if
@@ -4489,8 +4489,6 @@ red_char_device_vdi_port_init(RedCharDeviceVDIPort *self)
self->priv = RED_CHAR_DEVICE_VDIPORT_PRIVATE(self);
- ring_init(&self->priv->read_bufs);
-
self->priv->read_state = VDI_PORT_READ_STATE_READ_HEADER;
self->priv->receive_pos = (uint8_t *)&self->priv->vdi_chunk_header;
self->priv->receive_len = sizeof(self->priv->vdi_chunk_header);
diff --git a/server/stream.c b/server/stream.c
index 3431e50e..b91b1ea4 100644
--- a/server/stream.c
+++ b/server/stream.c
@@ -361,7 +361,8 @@ static void before_reattach_stream(DisplayChannel *display,
continue;
}
- if (red_pipe_item_is_linked(&dpi->dpi_pipe_item)) {
+ if (red_channel_client_pipe_item_is_linked(RED_CHANNEL_CLIENT(dcc),
+ &dpi->dpi_pipe_item)) {
#ifdef STREAM_STATS
agent->stats.num_drops_pipe++;
#endif