[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