[Spice-devel] [PATCH 3/4] worker: avoid blocking loop
Jonathon Jongsma
jjongsma at redhat.com
Wed Feb 3 00:19:37 CET 2016
Ack with minor changes below
Acked-by: Jonathon Jongsma <jjongsma at redhat.com>
On Fri, 2016-01-29 at 10:53 +0000, Frediano Ziglio wrote:
> Make sure we process commands after we can send data to client.
> If during processing we detected that there was too data in the clients
too much data
> queues the processing of commands just stop till the next iteration.
> However if all data are pushed in a single iteration of the loop
> and commands were already processed there were the (remote) possibility
there *was* the
> that the loop hangs till a separate event (like a screen resize on
> client window) arrive.
> I manage to reproduce and after half an hour no events arrived.
> This patch detect that processing was stuck and now we can process new
> commands and force a new iteration.
>
> Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
> ---
> server/red-worker.c | 14 ++++++++++++++
> 1 file changed, 14 insertions(+)
>
> diff --git a/server/red-worker.c b/server/red-worker.c
> index cf8e73d..8c79628 100644
> --- a/server/red-worker.c
> +++ b/server/red-worker.c
> @@ -69,6 +69,7 @@ struct RedWorker {
>
> DisplayChannel *display_channel;
> uint32_t display_poll_tries;
> + bool was_blocked;
>
> CursorChannel *cursor_channel;
> uint32_t cursor_poll_tries;
> @@ -196,6 +197,7 @@ static int red_process_cursor(RedWorker *worker, int
> *ring_is_empty)
> }
> n++;
> }
> + worker->was_blocked = true;
> return n;
> }
>
> @@ -318,9 +320,16 @@ static int red_process_display(RedWorker *worker, int
> *ring_is_empty)
> return n;
> }
> }
> + worker->was_blocked = true;
> return n;
> }
>
> +static bool red_process_is_blocked(RedWorker *worker)
> +{
> + return red_channel_max_pipe_size(RED_CHANNEL(worker->cursor_channel)) >
> MAX_PIPE_SIZE ||
> + red_channel_max_pipe_size(RED_CHANNEL(worker->display_channel)) >
> MAX_PIPE_SIZE;
> +}
> +
> static void red_disconnect_display(RedWorker *worker)
> {
> spice_warning("update timeout");
> @@ -1416,6 +1425,10 @@ static gboolean worker_source_prepare(GSource *source,
> gint *p_timeout)
> if (*p_timeout == 0)
> return TRUE;
>
> + if (worker->was_blocked && !red_process_is_blocked(worker)) {
> + return TRUE;
> + }
> +
> return FALSE;
> }
>
> @@ -1445,6 +1458,7 @@ static gboolean worker_source_dispatch(GSource *source,
> GSourceFunc callback,
> stream_timeout(display);
>
> worker->event_timeout = INF_EVENT_WAIT;
> + worker->was_blocked = false;
> red_process_cursor(worker, &ring_is_empty);
> red_process_display(worker, &ring_is_empty);
>
More information about the Spice-devel
mailing list