[Spice-devel] [PATCH 1/2] Change GList in GQueue
Frediano Ziglio
fziglio at redhat.com
Mon Sep 12 15:32:02 UTC 2016
This patch is intended to be merged into "RedChannelClient: store pipe
items in a GList".
GQueue improve GList for pipe usage as tail inserting/removal/access
are O(1) instead of O(n).
Also getting the number of items is O(1) instead of O(n).
Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
---
server/dcc-send.c | 12 ++++----
server/dcc.c | 2 +-
server/display-channel.c | 5 +---
server/red-channel-client-private.h | 2 +-
server/red-channel-client.c | 58 +++++++++++++++++--------------------
server/red-channel-client.h | 2 +-
6 files changed, 36 insertions(+), 45 deletions(-)
diff --git a/server/dcc-send.c b/server/dcc-send.c
index 187eaca..8bcba77 100644
--- a/server/dcc-send.c
+++ b/server/dcc-send.c
@@ -189,9 +189,8 @@ static int is_brush_lossy(RedChannelClient *rcc, SpiceBrush *brush,
static RedPipeItem *dcc_get_tail(DisplayChannelClient *dcc)
{
- GList *pipe = red_channel_client_get_pipe(RED_CHANNEL_CLIENT(dcc));
- GList *last = g_list_last(pipe);
- return last->data;
+ GQueue *pipe = red_channel_client_get_pipe(RED_CHANNEL_CLIENT(dcc));
+ return g_queue_peek_tail(pipe);
}
static void red_display_add_image_to_pixmap_cache(RedChannelClient *rcc,
@@ -623,7 +622,7 @@ static int pipe_rendered_drawables_intersect_with_areas(DisplayChannelClient *dc
spice_assert(num_surfaces);
- for (l = red_channel_client_get_pipe(RED_CHANNEL_CLIENT(dcc)); l != NULL; l = l->next) {
+ for (l = red_channel_client_get_pipe(RED_CHANNEL_CLIENT(dcc))->head; l != NULL; l = l->next) {
Drawable *drawable;
RedPipeItem *pipe_item = l->data;
@@ -704,7 +703,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;
- GList *l, *pipe;
+ GList *l;
+ GQueue *pipe;
resent_surface_ids[0] = first_surface_id;
resent_areas[0] = *first_area;
@@ -713,7 +713,7 @@ 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 (l = g_list_last(pipe); l != NULL; l = l->prev) {
+ for (l = pipe->tail; l != NULL; l = l->prev) {
RedPipeItem *pipe_item = l->data;
Drawable *drawable;
RedDrawablePipeItem *dpi;
diff --git a/server/dcc.c b/server/dcc.c
index b12d034..0d672df 100644
--- a/server/dcc.c
+++ b/server/dcc.c
@@ -78,7 +78,7 @@ 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;
+ l = rcc->priv->pipe.head;
while (l != NULL) {
GList *cur = l;
Drawable *drawable;
diff --git a/server/display-channel.c b/server/display-channel.c
index bd2907f..de25161 100644
--- a/server/display-channel.c
+++ b/server/display-channel.c
@@ -331,10 +331,7 @@ static void drawable_remove_from_pipes(Drawable *drawable)
dpi = SPICE_UPCAST(RedDrawablePipeItem, item);
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);
- }
+ 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 b13f905..8eaa570 100644
--- a/server/red-channel-client-private.h
+++ b/server/red-channel-client-private.h
@@ -59,7 +59,7 @@ struct RedChannelClientPrivate
int during_send;
int id; // debugging purposes
- GList *pipe;
+ GQueue pipe;
RedChannelCapabilities remote_caps;
int is_mini_header;
diff --git a/server/red-channel-client.c b/server/red-channel-client.c
index 9f678d7..89ab679 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 == NULL) {
+ && 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,9 +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 = g_list_remove(rcc->priv->pipe, item);
+ return g_queue_remove(&rcc->priv->pipe, item);
}
static void red_channel_client_set_remote_caps(RedChannelClient* rcc,
@@ -680,7 +680,7 @@ RedChannelClient *red_channel_client_create(int size, RedChannel *channel, RedCl
goto error;
}
- rcc->priv->pipe = NULL;
+ g_queue_init(&rcc->priv->pipe);
stream->watch = channel->core->watch_add(channel->core,
stream->socket,
@@ -741,7 +741,7 @@ RedChannelClient *red_channel_client_create_dummy(int size,
rcc->incoming.header.data = rcc->incoming.header_buf;
rcc->incoming.serial = 1;
- rcc->priv->pipe = NULL;
+ g_queue_init(&rcc->priv->pipe);
rcc->priv->dummy = TRUE;
rcc->priv->dummy_connected = TRUE;
@@ -1037,17 +1037,11 @@ 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)
- || !(l = g_list_last(rcc->priv->pipe))) {
+ || red_channel_client_waiting_for_ack(rcc)) {
return NULL;
}
- item = l->data;
- rcc->priv->pipe = g_list_delete_link(rcc->priv->pipe, l);
- 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) && rcc->priv->pipe == NULL
+ 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);
@@ -1294,7 +1288,7 @@ static inline gboolean prepare_pipe_add(RedChannelClient *rcc, RedPipeItem *item
red_pipe_item_unref(item);
return FALSE;
}
- if (rcc->priv->pipe == NULL && 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);
@@ -1308,7 +1302,7 @@ void red_channel_client_pipe_add(RedChannelClient *rcc, RedPipeItem *item)
if (!prepare_pipe_add(rcc, item)) {
return;
}
- rcc->priv->pipe = g_list_prepend(rcc->priv->pipe, item);
+ g_queue_push_head(&rcc->priv->pipe, item);
}
void red_channel_client_pipe_add_push(RedChannelClient *rcc, RedPipeItem *item)
@@ -1327,16 +1321,16 @@ void red_channel_client_pipe_add_after(RedChannelClient *rcc,
if (!prepare_pipe_add(rcc, item)) {
return;
}
- prev = g_list_find(rcc->priv->pipe, pos);
+ prev = g_queue_find(&rcc->priv->pipe, pos);
g_return_if_fail(prev != NULL);
- rcc->priv->pipe = g_list_insert_before(rcc->priv->pipe, prev->next, item);
+ g_queue_insert_after(&rcc->priv->pipe, prev, item);
}
int red_channel_client_pipe_item_is_linked(RedChannelClient *rcc,
RedPipeItem *item)
{
- return g_list_find(rcc->priv->pipe, item) != NULL;
+ return g_queue_find(&rcc->priv->pipe, item) != NULL;
}
void red_channel_client_pipe_add_tail(RedChannelClient *rcc,
@@ -1345,7 +1339,7 @@ void red_channel_client_pipe_add_tail(RedChannelClient *rcc,
if (!prepare_pipe_add(rcc, item)) {
return;
}
- rcc->priv->pipe = g_list_append(rcc->priv->pipe, item);
+ g_queue_push_tail(&rcc->priv->pipe, item);
}
void red_channel_client_pipe_add_tail_and_push(RedChannelClient *rcc, RedPipeItem *item)
@@ -1353,7 +1347,7 @@ void red_channel_client_pipe_add_tail_and_push(RedChannelClient *rcc, RedPipeIte
if (!prepare_pipe_add(rcc, item)) {
return;
}
- rcc->priv->pipe = g_list_append(rcc->priv->pipe, item);
+ g_queue_push_tail(&rcc->priv->pipe, item);
red_channel_client_push(rcc);
}
@@ -1379,17 +1373,17 @@ 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 == NULL);
+ return g_queue_is_empty(&rcc->priv->pipe);
}
uint32_t red_channel_client_get_pipe_size(RedChannelClient *rcc)
{
- return g_list_length(rcc->priv->pipe);
+ return g_queue_get_length(&rcc->priv->pipe);
}
-GList* red_channel_client_get_pipe(RedChannelClient *rcc)
+GQueue* red_channel_client_get_pipe(RedChannelClient *rcc)
{
- return rcc->priv->pipe;
+ return &rcc->priv->pipe;
}
gboolean red_channel_client_is_mini_header(RedChannelClient *rcc)
@@ -1419,14 +1413,13 @@ 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)
{
- GList *l;
+ RedPipeItem *item;
if (rcc) {
red_channel_client_clear_sent_item(rcc);
}
- while ((l = rcc->priv->pipe)) {
- red_pipe_item_unref(l->data);
- rcc->priv->pipe = g_list_delete_link(rcc->priv->pipe, l);
+ while ((item = g_queue_pop_head(&rcc->priv->pipe)) != NULL) {
+ red_pipe_item_unref(item);
}
}
@@ -1611,7 +1604,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 != NULL) {
+ 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));
@@ -1626,8 +1619,9 @@ 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);
- red_pipe_item_unref(item);
+ if (red_channel_client_pipe_remove(rcc, item)) {
+ red_pipe_item_unref(item);
+ }
}
/* client mutex should be locked before this call */
diff --git a/server/red-channel-client.h b/server/red-channel-client.h
index 249e7fe..e77936d 100644
--- a/server/red-channel-client.h
+++ b/server/red-channel-client.h
@@ -114,7 +114,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);
-GList* 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);
--
2.7.4
More information about the Spice-devel
mailing list