diff options
author | Jonathon Jongsma <jjongsma@redhat.com> | 2015-10-01 10:39:18 -0500 |
---|---|---|
committer | Jonathon Jongsma <jjongsma@redhat.com> | 2016-09-01 17:42:59 -0500 |
commit | 2f5d1f575929f36ea7a549d4a5feffbd2952a725 (patch) | |
tree | 3eee327c5cf1c998d4ab8ce5f20d5aeaa5d01e54 | |
parent | b97688634b674a6846e50764c069b70207baa39a (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.c | 2 | ||||
-rw-r--r-- | server/dcc-send.c | 23 | ||||
-rw-r--r-- | server/dcc.c | 22 | ||||
-rw-r--r-- | server/display-channel.c | 7 | ||||
-rw-r--r-- | server/red-channel-client-private.h | 3 | ||||
-rw-r--r-- | server/red-channel-client.c | 69 | ||||
-rw-r--r-- | server/red-pipe-item.c | 1 | ||||
-rw-r--r-- | server/red-pipe-item.h | 6 | ||||
-rw-r--r-- | server/reds.c | 14 | ||||
-rw-r--r-- | server/stream.c | 3 |
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 |