[Spice-devel] [PATCH 04/11] Use a marker instead of checking a RedPipeItem presence
Frediano Ziglio
fziglio at redhat.com
Fri May 20 13:01:42 UTC 2016
This avoids having to retain a pointer just to check item is still in
the queue with ring_item_is_linked(&item->link).
Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
---
server/red-channel.c | 30 ++++++++++++++++++++++++++----
server/red-channel.h | 1 +
2 files changed, 27 insertions(+), 4 deletions(-)
diff --git a/server/red-channel.c b/server/red-channel.c
index 23defc0..c0a9501 100644
--- a/server/red-channel.c
+++ b/server/red-channel.c
@@ -49,6 +49,11 @@ typedef struct RedEmptyMsgPipeItem {
int msg;
} RedEmptyMsgPipeItem;
+typedef struct MarkerPipeItem {
+ RedPipeItem base;
+ gboolean *item_in_pipe;
+} MarkerPipeItem;
+
#define PING_TEST_TIMEOUT_MS (MSEC_PER_SEC * 15)
#define PING_TEST_IDLE_NET_TIMEOUT_MS (MSEC_PER_SEC / 10)
@@ -574,6 +579,8 @@ static void red_channel_client_send_item(RedChannelClient *rcc, RedPipeItem *ite
case RED_PIPE_ITEM_TYPE_PING:
red_channel_client_send_ping(rcc);
break;
+ case RED_PIPE_ITEM_TYPE_MARKER:
+ break;
default:
rcc->channel->channel_cbs.send_item(rcc, item);
break;
@@ -2358,13 +2365,21 @@ int red_channel_client_wait_outgoing_item(RedChannelClient *rcc,
}
}
+static void marker_pipe_item_free(MarkerPipeItem *item)
+{
+ if (item->item_in_pipe) {
+ *item->item_in_pipe = FALSE;
+ }
+ free(item);
+}
+
/* 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,
int64_t timeout)
{
uint64_t end_time;
- int item_in_pipe;
+ gboolean item_in_pipe;
spice_info(NULL);
@@ -2374,7 +2389,13 @@ int red_channel_client_wait_pipe_item_sent(RedChannelClient *rcc,
end_time = UINT64_MAX;
}
- red_pipe_item_ref(item);
+ MarkerPipeItem *mark_item = spice_new0(MarkerPipeItem, 1);
+
+ red_pipe_item_init_full(&mark_item->base, RED_PIPE_ITEM_TYPE_MARKER,
+ (GDestroyNotify)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);
if (red_channel_client_blocked(rcc)) {
red_channel_client_receive(rcc);
@@ -2382,7 +2403,7 @@ int red_channel_client_wait_pipe_item_sent(RedChannelClient *rcc,
}
red_channel_client_push(rcc);
- while((item_in_pipe = ring_item_is_linked(&item->link)) &&
+ while(item_in_pipe &&
(timeout == -1 || spice_get_monotonic_time_ns() < end_time)) {
usleep(CHANNEL_BLOCKED_SLEEP_DURATION);
red_channel_client_receive(rcc);
@@ -2390,8 +2411,9 @@ int red_channel_client_wait_pipe_item_sent(RedChannelClient *rcc,
red_channel_client_push(rcc);
}
- red_pipe_item_unref(item);
if (item_in_pipe) {
+ // still on the queue, make sure won't overwrite the stack variable
+ mark_item->item_in_pipe = NULL;
spice_warning("timeout");
return FALSE;
} else {
diff --git a/server/red-channel.h b/server/red-channel.h
index 8e8845e..c4eb436 100644
--- a/server/red-channel.h
+++ b/server/red-channel.h
@@ -143,6 +143,7 @@ enum {
RED_PIPE_ITEM_TYPE_MIGRATE,
RED_PIPE_ITEM_TYPE_EMPTY_MSG,
RED_PIPE_ITEM_TYPE_PING,
+ RED_PIPE_ITEM_TYPE_MARKER,
RED_PIPE_ITEM_TYPE_CHANNEL_BASE=101,
};
--
2.7.4
More information about the Spice-devel
mailing list