Make sure we process commands after we can send data to client. If during processing we detected that there was too much data in the clients 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 was the (remote) possibility 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@xxxxxxxxxx> Acked-by: Jonathon Jongsma <jjongsma@xxxxxxxxxx> --- server/red-worker.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/server/red-worker.c b/server/red-worker.c index 031350a..45a597f 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; + gboolean 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); -- 2.4.3 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel