[Spice-devel] [PATCH spice-gtk 1/2] clipboard: prevent reentering main loop if main channel is busy

Marc-André Lureau marcandre.lureau at gmail.com
Thu May 15 04:12:42 PDT 2014


From: Marc-André Lureau <marcandre.lureau at gmail.com>

The main channel must be idle to avoid entering the nested loop,
or it will never reach the condition to leave it.

This should not happen. It can happen currently when the remote send a
clipboard request while the clipboard is grabbed by the remote. In this
case, while the clipboard-request signal is emitted by main channel, the
clipboard_get() loop is entered, but the main coroutine will not be
woken up to proceed with the request, the main channel will remain
"frozen" and it won't be possible to leave cleanly from the inner loop.
The application appears to be frozen, because it can't quit properly.

Related to:
https://bugzilla.redhat.com/show_bug.cgi?id=1083489
---
 gtk/gio-coroutine.h     | 11 +++++++++++
 gtk/spice-gtk-session.c |  1 +
 2 files changed, 12 insertions(+)

diff --git a/gtk/gio-coroutine.h b/gtk/gio-coroutine.h
index 1c4094e..50c1b7c 100644
--- a/gtk/gio-coroutine.h
+++ b/gtk/gio-coroutine.h
@@ -35,6 +35,17 @@ struct _GCoroutine
     guint condition_id;
 };
 
+static inline gboolean g_coroutine_is_idle(GCoroutine *self)
+{
+    gboolean idle;
+
+    g_return_val_if_fail(self != NULL, FALSE);
+
+    idle = self->wait_id != 0 || self->condition_id != 0;
+
+    return idle;
+}
+
 /*
  * A special GSource impl which allows us to wait on a certain
  * condition to be satisfied. This is effectively a boolean test
diff --git a/gtk/spice-gtk-session.c b/gtk/spice-gtk-session.c
index eab7e2f..5b8639c 100644
--- a/gtk/spice-gtk-session.c
+++ b/gtk/spice-gtk-session.c
@@ -626,6 +626,7 @@ static void clipboard_get(GtkClipboard *clipboard,
     g_return_if_fail(selection != -1);
     g_return_if_fail(info < SPICE_N_ELEMENTS(atom2agent));
     g_return_if_fail(s->main != NULL);
+    g_return_if_fail(g_coroutine_is_idle(&SPICE_CHANNEL(s->main)->priv->coroutine));
 
     ri.selection_data = selection_data;
     ri.info = info;
-- 
1.9.0



More information about the Spice-devel mailing list