[Spice-devel] [PATCHv3 spice-gtk 13/14] channel: add spice_channel_get_error()

Marc-André Lureau marcandre.lureau at gmail.com
Mon Feb 17 13:35:52 PST 2014


Add a function to retrieve the last GError from a channel, this may be
useful to provide additional error details to the client.
---
 doc/reference/spice-gtk-sections.txt |  1 +
 gtk/map-file                         |  1 +
 gtk/spice-channel-priv.h             |  1 +
 gtk/spice-channel.c                  | 30 +++++++++++++++++++++++++++---
 gtk/spice-channel.h                  |  2 ++
 gtk/spice-glib-sym-file              |  1 +
 gtk/spice-session-priv.h             |  2 +-
 gtk/spice-session.c                  |  6 +++---
 gtk/spicy.c                          |  6 ++++++
 9 files changed, 43 insertions(+), 7 deletions(-)

diff --git a/doc/reference/spice-gtk-sections.txt b/doc/reference/spice-gtk-sections.txt
index 411ca0e..9f0cf67 100644
--- a/doc/reference/spice-gtk-sections.txt
+++ b/doc/reference/spice-gtk-sections.txt
@@ -102,6 +102,7 @@ spice_channel_string_to_type
 spice_channel_set_capability
 spice_channel_flush_async
 spice_channel_flush_finish
+spice_channel_get_error
 <SUBSECTION Standard>
 SPICE_TYPE_CHANNEL_EVENT
 spice_channel_event_get_type
diff --git a/gtk/map-file b/gtk/map-file
index 82a10eb..0067960 100644
--- a/gtk/map-file
+++ b/gtk/map-file
@@ -7,6 +7,7 @@ spice_channel_connect;
 spice_channel_destroy;
 spice_channel_disconnect;
 spice_channel_event_get_type;
+spice_channel_get_error;
 spice_channel_get_type;
 spice_channel_new;
 spice_channel_open_fd;
diff --git a/gtk/spice-channel-priv.h b/gtk/spice-channel-priv.h
index f38156e..607c0d4 100644
--- a/gtk/spice-channel-priv.h
+++ b/gtk/spice-channel-priv.h
@@ -136,6 +136,7 @@ struct _SpiceChannelPrivate {
     GSList                      *flushing;
 
     gboolean                    disable_channel_msg;
+    GError                      *error;
 };
 
 SpiceMsgIn *spice_msg_in_new(SpiceChannel *channel);
diff --git a/gtk/spice-channel.c b/gtk/spice-channel.c
index 1b8ec10..a9c1076 100644
--- a/gtk/spice-channel.c
+++ b/gtk/spice-channel.c
@@ -154,6 +154,8 @@ static void spice_channel_dispose(GObject *gobject)
          c->session = NULL;
     }
 
+    g_clear_error(&c->error);
+
     /* Chain up to the parent class */
     if (G_OBJECT_CLASS(spice_channel_parent_class)->dispose)
         G_OBJECT_CLASS(spice_channel_parent_class)->dispose(gobject);
@@ -317,7 +319,9 @@ static void spice_channel_class_init(SpiceChannelClass *klass)
      * @event: a #SpiceChannelEvent
      *
      * The #SpiceChannel::channel-event signal is emitted when the
-     * state of the connection change.
+     * state of the connection is changed. In case of errors,
+     * spice_channel_get_error() may provide additional informations
+     * on the source of the error.
      **/
     signals[SPICE_CHANNEL_EVENT] =
         g_signal_new("channel-event",
@@ -2220,6 +2224,25 @@ static int spice_channel_load_ca(SpiceChannel *channel)
     return count;
 }
 
+/**
+ * spice_channel_get_error:
+ * @channel:
+ *
+ * Retrieves the #GError currently set on channel, if the #SpiceChannel
+ * is in error state and can provide additional error details.
+ *
+ * Returns: the pointer to the error, or %NULL
+ * Since: 0.24
+ **/
+const GError* spice_channel_get_error(SpiceChannel *self)
+{
+    SpiceChannelPrivate *c;
+
+    g_return_val_if_fail(SPICE_IS_CHANNEL(self), NULL);
+    c = self->priv;
+
+    return c->error;
+}
 
 /* coroutine context */
 static void *spice_channel_coroutine(void *data)
@@ -2257,15 +2280,16 @@ static void *spice_channel_coroutine(void *data)
 
 
 reconnect:
-    c->conn = spice_session_channel_open_host(c->session, channel, &c->tls);
+    c->conn = spice_session_channel_open_host(c->session, channel, &c->tls, &c->error);
     if (c->conn == NULL) {
-        if (!c->tls) {
+        if (!c->error && !c->tls) {
             CHANNEL_DEBUG(channel, "trying with TLS port");
             c->tls = true; /* FIXME: does that really work with provided fd */
             goto reconnect;
         } else {
             CHANNEL_DEBUG(channel, "Connect error");
             emit_main_context(channel, SPICE_CHANNEL_EVENT, SPICE_CHANNEL_ERROR_CONNECT);
+            g_clear_error(&c->error);
             goto cleanup;
         }
     }
diff --git a/gtk/spice-channel.h b/gtk/spice-channel.h
index 705dddf..1c303b4 100644
--- a/gtk/spice-channel.h
+++ b/gtk/spice-channel.h
@@ -123,6 +123,8 @@ void spice_channel_set_capability(SpiceChannel *channel, guint32 cap);
 const gchar* spice_channel_type_to_string(gint type);
 gint spice_channel_string_to_type(const gchar *str);
 
+const GError* spice_channel_get_error(SpiceChannel *channel);
+
 G_END_DECLS
 
 #endif /* __SPICE_CLIENT_CHANNEL_H__ */
diff --git a/gtk/spice-glib-sym-file b/gtk/spice-glib-sym-file
index 3dc709a..9d5001a 100644
--- a/gtk/spice-glib-sym-file
+++ b/gtk/spice-glib-sym-file
@@ -7,6 +7,7 @@ spice_channel_disconnect
 spice_channel_event_get_type
 spice_channel_flush_async
 spice_channel_flush_finish
+spice_channel_get_error
 spice_channel_get_type
 spice_channel_new
 spice_channel_open_fd
diff --git a/gtk/spice-session-priv.h b/gtk/spice-session-priv.h
index 85a1dad..cf9f9d1 100644
--- a/gtk/spice-session-priv.h
+++ b/gtk/spice-session-priv.h
@@ -119,7 +119,7 @@ int spice_session_get_connection_id(SpiceSession *session);
 gboolean spice_session_get_client_provided_socket(SpiceSession *session);
 
 GSocketConnection* spice_session_channel_open_host(SpiceSession *session, SpiceChannel *channel,
-                                                   gboolean *use_tls);
+                                                   gboolean *use_tls, GError **error);
 void spice_session_channel_new(SpiceSession *session, SpiceChannel *channel);
 void spice_session_channel_destroy(SpiceSession *session, SpiceChannel *channel);
 void spice_session_channel_migrate(SpiceSession *session, SpiceChannel *channel);
diff --git a/gtk/spice-session.c b/gtk/spice-session.c
index 19057bf..5e76b5f 100644
--- a/gtk/spice-session.c
+++ b/gtk/spice-session.c
@@ -1796,7 +1796,7 @@ static gboolean connect_timeout(gpointer data)
 /* coroutine context */
 G_GNUC_INTERNAL
 GSocketConnection* spice_session_channel_open_host(SpiceSession *session, SpiceChannel *channel,
-                                                   gboolean *use_tls)
+                                                   gboolean *use_tls, GError **error)
 {
     SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(session);
     SpiceChannelPrivate *c = channel->priv;
@@ -1845,8 +1845,8 @@ GSocketConnection* spice_session_channel_open_host(SpiceSession *session, SpiceC
 #endif
 
     if (open_host.error != NULL) {
-        g_warning("open host: %s", open_host.error->message);
-        g_clear_error(&open_host.error);
+        SPICE_DEBUG("open host: %s", open_host.error->message);
+        g_propagate_error(error, open_host.error);
     } else if (open_host.connection != NULL) {
         GSocket *socket;
         socket = g_socket_connection_get_socket(open_host.connection);
diff --git a/gtk/spicy.c b/gtk/spicy.c
index 3e280a0..038d622 100644
--- a/gtk/spicy.c
+++ b/gtk/spicy.c
@@ -1208,6 +1208,7 @@ static void recent_add(SpiceSession *session)
 static void main_channel_event(SpiceChannel *channel, SpiceChannelEvent event,
                                gpointer data)
 {
+    const GError *error = NULL;
     spice_connection *conn = data;
     char password[64];
     int rc;
@@ -1231,7 +1232,12 @@ static void main_channel_event(SpiceChannel *channel, SpiceChannelEvent event,
     case SPICE_CHANNEL_ERROR_TLS:
     case SPICE_CHANNEL_ERROR_LINK:
     case SPICE_CHANNEL_ERROR_CONNECT:
+        error = spice_channel_get_error(channel);
         g_message("main channel: failed to connect");
+        if (error) {
+            g_message("channel error: %s", error->message);
+        }
+
         rc = connect_dialog(conn->session);
         if (rc == 0) {
             connection_connect(conn);
-- 
1.8.4.2



More information about the Spice-devel mailing list