[Spice-devel] [PATCH 04/11] Use a marker instead of checking a RedPipeItem presence
Jonathon Jongsma
jjongsma at redhat.com
Fri May 20 20:29:51 UTC 2016
I would prefer a more elegant long-term solution, but this is OK as a short-term
solution
Acked-by: Jonathon Jongsma <jjongsma at redhat.com>
On Fri, 2016-05-20 at 14:01 +0100, Frediano Ziglio wrote:
> 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,
> };
More information about the Spice-devel
mailing list