[PATCH v2 5/9] RedChannelClient: store pipe items in a GQueue

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Instead of using a Ring (and having a ring item link in every pipe
item), store them in a GQueue. This also necesitated changing
RedCharDeviceVDIPort->priv->read_bufs to a GList as well.

Also Optimise client pipe by passing pipe position instead of data.
This avoids having 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>
---
Changes in v2:
 - Switch to GQueue instead of GList
 - squashed Frediano's patches

 server/cursor-channel.c             |  2 -
 server/dcc-send.c                   | 27 +++++------
 server/dcc.c                        | 30 +++++-------
 server/dcc.h                        |  2 +-
 server/display-channel.c            |  8 +--
 server/red-channel-client-private.h |  3 +-
 server/red-channel-client.c         | 97 +++++++++++++++++++++++--------------
 server/red-channel-client.h         |  6 ++-
 server/red-pipe-item.c              |  1 -
 server/red-pipe-item.h              |  6 ---
 server/reds.c                       | 14 +++---
 server/stream.c                     |  3 +-
 12 files changed, 103 insertions(+), 96 deletions(-)

diff --git a/server/cursor-channel.c b/server/cursor-channel.c
index 52c8e2d..8786ac6 100644
--- a/server/cursor-channel.c
+++ b/server/cursor-channel.c
@@ -189,8 +189,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 0635afa..7392378 100644
--- a/server/dcc-send.c
+++ b/server/dcc-send.c
@@ -187,9 +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)
 {
-    return (RedPipeItem*)ring_get_tail(red_channel_client_get_pipe(RED_CHANNEL_CLIENT(dcc)));
+    return red_channel_client_get_pipe(RED_CHANNEL_CLIENT(dcc))->tail;
 }
 
 static void red_display_add_image_to_pixmap_cache(RedChannelClient *rcc,
@@ -617,17 +617,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_get_pipe(RED_CHANNEL_CLIENT(dcc));
 
-    for (pipe_item = (RedPipeItem *)ring_get_head(pipe);
-         pipe_item;
-         pipe_item = (RedPipeItem *)ring_next(pipe, &pipe_item->link))
-    {
+    for (l = red_channel_client_get_pipe(RED_CHANNEL_CLIENT(dcc))->head; l != NULL; l = l->next) {
         Drawable *drawable;
+        RedPipeItem *pipe_item = l->data;
 
         if (pipe_item->type != RED_PIPE_ITEM_TYPE_DRAW)
             continue;
@@ -706,8 +702,8 @@ 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;
+    GQueue *pipe;
 
     resent_surface_ids[0] = first_surface_id;
     resent_areas[0] = *first_area;
@@ -716,9 +712,8 @@ static void red_pipe_replace_rendered_drawables_with_images(DisplayChannelClient
     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);
-         pipe_item;
-         pipe_item = (RedPipeItem *)ring_prev(pipe, &pipe_item->link)) {
+    for (l = pipe->tail; l != NULL; l = l->prev) {
+        RedPipeItem *pipe_item = l->data;
         Drawable *drawable;
         RedDrawablePipeItem *dpi;
         RedImageItem *image;
@@ -742,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 62e32c4..ddc1a59 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)
 {
-    Ring *ring;
-    RedPipeItem *item;
+    GList *l, *item_pos = NULL;
     int x;
     RedChannelClient *rcc;
 
@@ -78,13 +77,14 @@ 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))) {
+    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;
         if (item->type == RED_PIPE_ITEM_TYPE_DRAW) {
             dpi = SPICE_CONTAINEROF(item, RedDrawablePipeItem, dpi_pipe_item);
             drawable = dpi->drawable;
@@ -95,12 +95,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_pos(rcc, item_pos);
             continue;
         }
 
@@ -125,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 {
         /*
@@ -171,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 *pipe_item_pos,
                                          int can_lossy)
 {
     DisplayChannel *display = DCC_TO_DC(dcc);
@@ -221,8 +216,8 @@ RedImageItem *dcc_add_surface_area_image(DisplayChannelClient *dcc,
         }
     }
 
-    if (pos) {
-        red_channel_client_pipe_add_after(RED_CHANNEL_CLIENT(dcc), &item->base, pos);
+    if (pipe_item_pos) {
+        red_channel_client_pipe_add_after_pos(RED_CHANNEL_CLIENT(dcc), &item->base, pipe_item_pos);
     } else {
         red_channel_client_pipe_add(RED_CHANNEL_CLIENT(dcc), &item->base);
     }
@@ -289,7 +284,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/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/display-channel.c b/server/display-channel.c
index 000bb8c..e37b5ae 100644
--- a/server/display-channel.c
+++ b/server/display-channel.c
@@ -327,11 +327,11 @@ 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),
-                                                       &dpi->dpi_pipe_item);
-        }
+        rcc = RED_CHANNEL_CLIENT(dpi->dcc);
+        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 532bfa3..8eaa570 100644
--- a/server/red-channel-client-private.h
+++ b/server/red-channel-client-private.h
@@ -59,8 +59,7 @@ struct RedChannelClientPrivate
 
     int during_send;
     int id; // debugging purposes
-    Ring pipe;
-    uint32_t pipe_size;
+    GQueue pipe;
 
     RedChannelCapabilities remote_caps;
     int is_mini_header;
diff --git a/server/red-channel-client.c b/server/red-channel-client.c
index 0eed02b..50b295c 100644
--- a/server/red-channel-client.c
+++ b/server/red-channel-client.c
@@ -344,7 +344,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) {
+            && g_queue_is_empty(&rcc->priv->pipe)) {
             /* It is possible that the socket will become idle, so we may be able to test latency */
             red_channel_client_restart_ping_timer(rcc);
         }
@@ -352,10 +352,9 @@ void red_channel_client_on_out_msg_done(void *opaque)
 
 }
 
-static void red_channel_client_pipe_remove(RedChannelClient *rcc, RedPipeItem *item)
+static gboolean red_channel_client_pipe_remove(RedChannelClient *rcc, RedPipeItem *item)
 {
-    rcc->priv->pipe_size--;
-    ring_remove(&item->link);
+    return g_queue_remove(&rcc->priv->pipe, item);
 }
 
 static void red_channel_client_set_remote_caps(RedChannelClient* rcc,
@@ -681,8 +680,7 @@ RedChannelClient *red_channel_client_create(int size, RedChannel *channel, RedCl
         goto error;
     }
 
-    ring_init(&rcc->priv->pipe);
-    rcc->priv->pipe_size = 0;
+    g_queue_init(&rcc->priv->pipe);
 
     stream->watch = channel->core->watch_add(channel->core,
                                            stream->socket,
@@ -743,7 +741,7 @@ RedChannelClient *red_channel_client_create_dummy(int size,
 
     rcc->incoming.header.data = rcc->incoming.header_buf;
     rcc->incoming.serial = 1;
-    ring_init(&rcc->priv->pipe);
+    g_queue_init(&rcc->priv->pipe);
 
     rcc->priv->dummy = TRUE;
     rcc->priv->dummy_connected = TRUE;
@@ -1039,15 +1037,11 @@ void red_channel_client_send(RedChannelClient *rcc)
 
 static inline RedPipeItem *red_channel_client_pipe_item_get(RedChannelClient *rcc)
 {
-    RedPipeItem *item;
-
     if (!rcc || rcc->priv->send_data.blocked
-             || red_channel_client_waiting_for_ack(rcc)
-             || !(item = (RedPipeItem *)ring_get_tail(&rcc->priv->pipe))) {
+             || red_channel_client_waiting_for_ack(rcc)) {
         return NULL;
     }
-    red_channel_client_pipe_remove(rcc, item);
-    return item;
+    return g_queue_pop_tail(&rcc->priv->pipe);
 }
 
 void red_channel_client_push(RedChannelClient *rcc)
@@ -1072,7 +1066,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) && g_queue_is_empty(&rcc->priv->pipe)
         && rcc->priv->stream->watch) {
         rcc->priv->channel->core->watch_update_mask(rcc->priv->stream->watch,
                                                     SPICE_WATCH_EVENT_READ);
@@ -1286,7 +1280,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))) {
@@ -1294,20 +1288,21 @@ 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 (g_queue_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->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;
+    }
+    g_queue_push_head(&rcc->priv->pipe, item);
 }
 
 void red_channel_client_pipe_add_push(RedChannelClient *rcc, RedPipeItem *item)
@@ -1316,31 +1311,53 @@ 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 *pipe_item_pos)
+{
+    spice_assert(pipe_item_pos);
+    if (!prepare_pipe_add(rcc, item)) {
+        return;
+    }
+
+    g_queue_insert_after(&rcc->priv->pipe, pipe_item_pos, item);
+}
+
 void red_channel_client_pipe_add_after(RedChannelClient *rcc,
                                        RedPipeItem *item,
                                        RedPipeItem *pos)
 {
+    GList *prev;
+
     spice_assert(pos);
-    client_pipe_add(rcc, item, &pos->link);
+    prev = g_queue_find(&rcc->priv->pipe, pos);
+    g_return_if_fail(prev != NULL);
+
+    red_channel_client_pipe_add_after_pos(rcc, item, prev);
 }
 
 int red_channel_client_pipe_item_is_linked(RedChannelClient *rcc,
                                            RedPipeItem *item)
 {
-    return ring_item_is_linked(&item->link);
+    return g_queue_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;
+    }
+    g_queue_push_tail(&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;
     }
+    g_queue_push_tail(&rcc->priv->pipe, item);
+    red_channel_client_push(rcc);
 }
 
 void red_channel_client_pipe_add_type(RedChannelClient *rcc, int pipe_item_type)
@@ -1365,15 +1382,15 @@ 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 g_queue_is_empty(&rcc->priv->pipe);
 }
 
 uint32_t red_channel_client_get_pipe_size(RedChannelClient *rcc)
 {
-    return rcc->priv->pipe_size;
+    return g_queue_get_length(&rcc->priv->pipe);
 }
 
-Ring* red_channel_client_get_pipe(RedChannelClient *rcc)
+GQueue* red_channel_client_get_pipe(RedChannelClient *rcc)
 {
     return &rcc->priv->pipe;
 }
@@ -1410,11 +1427,9 @@ 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->priv->pipe))) {
-        ring_remove(&item->link);
+    while ((item = g_queue_pop_head(&rcc->priv->pipe)) != NULL) {
         red_pipe_item_unref(item);
     }
-    rcc->priv->pipe_size = 0;
 }
 
 void red_channel_client_ack_zero_messages_window(RedChannelClient *rcc)
@@ -1517,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;
@@ -1537,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);
@@ -1545,8 +1560,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);
@@ -1598,7 +1613,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) || !g_queue_is_empty(&rcc->priv->pipe)) {
         red_channel_client_disconnect(rcc);
     } else {
         spice_assert(red_channel_client_no_item_being_sent(rcc));
@@ -1613,7 +1628,17 @@ gboolean red_channel_client_no_item_being_sent(RedChannelClient *rcc)
 void red_channel_client_pipe_remove_and_release(RedChannelClient *rcc,
                                                 RedPipeItem *item)
 {
-    red_channel_client_pipe_remove(rcc, item);
+    if (red_channel_client_pipe_remove(rcc, item)) {
+        red_pipe_item_unref(item);
+    }
+}
+
+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);
 }
 
diff --git a/server/red-channel-client.h b/server/red-channel-client.h
index d2f7b3e..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 */
@@ -114,7 +116,7 @@ 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);
+GQueue* 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);
@@ -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);
diff --git a/server/red-pipe-item.c b/server/red-pipe-item.c
index 31262fa..d899610 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 bf13b0b..a589c68 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 a387eeb..ca10a7a 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;
@@ -806,15 +806,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);
@@ -827,7 +827,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
@@ -4483,8 +4483,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 c3877c7..9517fac 100644
--- a/server/stream.c
+++ b/server/stream.c
@@ -360,7 +360,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
-- 
2.7.4

_______________________________________________
Spice-devel mailing list
Spice-devel@xxxxxxxxxxxxxxxxxxxxx
https://lists.freedesktop.org/mailman/listinfo/spice-devel




[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]     [Monitors]