This avoid to have the search the data scanning all the queue changing the order of these operations from O(n) to O(1). Signed-off-by: Frediano Ziglio <fziglio@xxxxxxxxxx> --- server/dcc-send.c | 9 ++++----- server/dcc.c | 20 +++++++++----------- server/dcc.h | 2 +- server/red-channel-client.c | 32 +++++++++++++++++++++++++------- server/red-channel-client.h | 4 +++- 5 files changed, 42 insertions(+), 25 deletions(-) diff --git a/server/dcc-send.c b/server/dcc-send.c index 8bcba77..a22ee0b 100644 --- a/server/dcc-send.c +++ b/server/dcc-send.c @@ -187,10 +187,9 @@ static int is_brush_lossy(RedChannelClient *rcc, SpiceBrush *brush, } } -static RedPipeItem *dcc_get_tail(DisplayChannelClient *dcc) +static GList *dcc_get_tail(DisplayChannelClient *dcc) { - GQueue *pipe = red_channel_client_get_pipe(RED_CHANNEL_CLIENT(dcc)); - return g_queue_peek_tail(pipe); + return red_channel_client_get_pipe(RED_CHANNEL_CLIENT(dcc))->tail; } static void red_display_add_image_to_pixmap_cache(RedChannelClient *rcc, @@ -738,13 +737,13 @@ static void red_pipe_replace_rendered_drawables_with_images(DisplayChannelClient } image = dcc_add_surface_area_image(dcc, drawable->red_drawable->surface_id, - &drawable->red_drawable->bbox, pipe_item, TRUE); + &drawable->red_drawable->bbox, l, TRUE); resent_surface_ids[num_resent] = drawable->red_drawable->surface_id; resent_areas[num_resent] = drawable->red_drawable->bbox; num_resent++; spice_assert(image); - red_channel_client_pipe_remove_and_release(RED_CHANNEL_CLIENT(dcc), &dpi->dpi_pipe_item); + red_channel_client_pipe_remove_and_release_pos(RED_CHANNEL_CLIENT(dcc), l); pipe_item = &image->base; } } diff --git a/server/dcc.c b/server/dcc.c index 0d672df..ece37d9 100644 --- a/server/dcc.c +++ b/server/dcc.c @@ -68,8 +68,7 @@ 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) { - GList *l; - RedPipeItem *item = NULL; + GList *l, *item_pos = NULL; int x; RedChannelClient *rcc; @@ -78,15 +77,14 @@ int dcc_clear_surface_drawables_from_pipe(DisplayChannelClient *dcc, int surface no other drawable depends on them */ rcc = RED_CHANNEL_CLIENT(dcc); - l = rcc->priv->pipe.head; - while (l != NULL) { - GList *cur = l; + for (l = rcc->priv->pipe.head; l != NULL; item_pos = NULL) { Drawable *drawable; RedDrawablePipeItem *dpi = NULL; int depend_found = FALSE; + RedPipeItem *item = l->data; + item_pos = l; 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; @@ -97,7 +95,7 @@ int dcc_clear_surface_drawables_from_pipe(DisplayChannelClient *dcc, int surface } if (drawable->surface_id == surface_id) { - red_channel_client_pipe_remove_and_release(rcc, item); + red_channel_client_pipe_remove_and_release_pos(rcc, item_pos); continue; } @@ -122,8 +120,8 @@ int dcc_clear_surface_drawables_from_pipe(DisplayChannelClient *dcc, int surface return TRUE; } - if (item) { - return red_channel_client_wait_pipe_item_sent(RED_CHANNEL_CLIENT(dcc), item, + if (item_pos) { + return red_channel_client_wait_pipe_item_sent(RED_CHANNEL_CLIENT(dcc), item_pos, COMMON_CLIENT_TIMEOUT); } else { /* @@ -168,7 +166,7 @@ void dcc_create_surface(DisplayChannelClient *dcc, int surface_id) RedImageItem *dcc_add_surface_area_image(DisplayChannelClient *dcc, int surface_id, SpiceRect *area, - RedPipeItem *pos, + GList *pos, int can_lossy) { DisplayChannel *display = DCC_TO_DC(dcc); @@ -219,7 +217,7 @@ RedImageItem *dcc_add_surface_area_image(DisplayChannelClient *dcc, } if (pos) { - red_channel_client_pipe_add_after(RED_CHANNEL_CLIENT(dcc), &item->base, pos); + red_channel_client_pipe_add_after_pos(RED_CHANNEL_CLIENT(dcc), &item->base, pos); } else { red_channel_client_pipe_add(RED_CHANNEL_CLIENT(dcc), &item->base); } diff --git a/server/dcc.h b/server/dcc.h index d08e413..7f93186 100644 --- a/server/dcc.h +++ b/server/dcc.h @@ -129,7 +129,7 @@ void dcc_push_surface_image (DisplayCha RedImageItem * dcc_add_surface_area_image (DisplayChannelClient *dcc, int surface_id, SpiceRect *area, - RedPipeItem *pos, + GList *pos, int can_lossy); void dcc_palette_cache_reset (DisplayChannelClient *dcc); void dcc_palette_cache_palette (DisplayChannelClient *dcc, diff --git a/server/red-channel-client.c b/server/red-channel-client.c index 89ab679..563d888 100644 --- a/server/red-channel-client.c +++ b/server/red-channel-client.c @@ -1311,20 +1311,29 @@ void red_channel_client_pipe_add_push(RedChannelClient *rcc, RedPipeItem *item) red_channel_client_push(rcc); } +void red_channel_client_pipe_add_after_pos(RedChannelClient *rcc, + RedPipeItem *item, + GList *pos) +{ + spice_assert(pos); + if (!prepare_pipe_add(rcc, item)) { + return; + } + + g_queue_insert_after(&rcc->priv->pipe, pos, item); +} + void red_channel_client_pipe_add_after(RedChannelClient *rcc, RedPipeItem *item, RedPipeItem *pos) { - GList *prev = NULL; + GList *prev; spice_assert(pos); - if (!prepare_pipe_add(rcc, item)) { - return; - } prev = g_queue_find(&rcc->priv->pipe, pos); g_return_if_fail(prev != NULL); - g_queue_insert_after(&rcc->priv->pipe, prev, item); + red_channel_client_pipe_add_after_pos(rcc, item, prev); } int red_channel_client_pipe_item_is_linked(RedChannelClient *rcc, @@ -1523,7 +1532,7 @@ static void marker_pipe_item_free(RedPipeItem *base) /* TODO: more evil sync stuff. anything with the word wait in it's name. */ int red_channel_client_wait_pipe_item_sent(RedChannelClient *rcc, - RedPipeItem *item, + GList *item_pos, int64_t timeout) { uint64_t end_time; @@ -1543,7 +1552,7 @@ int red_channel_client_wait_pipe_item_sent(RedChannelClient *rcc, marker_pipe_item_free); item_in_pipe = TRUE; mark_item->item_in_pipe = &item_in_pipe; - red_channel_client_pipe_add_after(rcc, &mark_item->base, item); + red_channel_client_pipe_add_after_pos(rcc, &mark_item->base, item_pos); if (red_channel_client_is_blocked(rcc)) { red_channel_client_receive(rcc); @@ -1624,6 +1633,15 @@ void red_channel_client_pipe_remove_and_release(RedChannelClient *rcc, } } +void red_channel_client_pipe_remove_and_release_pos(RedChannelClient *rcc, + GList *item_pos) +{ + RedPipeItem *item = item_pos->data; + + g_queue_delete_link(&rcc->priv->pipe, item_pos); + red_pipe_item_unref(item); +} + /* client mutex should be locked before this call */ gboolean red_channel_client_set_migration_seamless(RedChannelClient *rcc) { diff --git a/server/red-channel-client.h b/server/red-channel-client.h index e77936d..b2386d3 100644 --- a/server/red-channel-client.h +++ b/server/red-channel-client.h @@ -105,8 +105,10 @@ void red_channel_client_start_connectivity_monitoring(RedChannelClient *rcc, uin void red_channel_client_pipe_add_push(RedChannelClient *rcc, RedPipeItem *item); void red_channel_client_pipe_add(RedChannelClient *rcc, RedPipeItem *item); void red_channel_client_pipe_add_after(RedChannelClient *rcc, RedPipeItem *item, RedPipeItem *pos); +void red_channel_client_pipe_add_after_pos(RedChannelClient *rcc, RedPipeItem *item, GList *pos); int red_channel_client_pipe_item_is_linked(RedChannelClient *rcc, RedPipeItem *item); void red_channel_client_pipe_remove_and_release(RedChannelClient *rcc, RedPipeItem *item); +void red_channel_client_pipe_remove_and_release_pos(RedChannelClient *rcc, GList *item_pos); void red_channel_client_pipe_add_tail(RedChannelClient *rcc, RedPipeItem *item); void red_channel_client_pipe_add_tail_and_push(RedChannelClient *rcc, RedPipeItem *item); /* for types that use this routine -> the pipe item should be freed */ @@ -150,7 +152,7 @@ void red_channel_client_set_header_sub_list(RedChannelClient *rcc, uint32_t sub_ */ int red_channel_client_wait_pipe_item_sent(RedChannelClient *rcc, - RedPipeItem *item, + GList *item_pos, int64_t timeout); int red_channel_client_wait_outgoing_item(RedChannelClient *rcc, int64_t timeout); -- 2.7.4 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel