[Spice-devel] [spice-gtk 2/2] smartcard: Only init manager once

Christophe Fergeau cfergeau at redhat.com
Thu Jul 11 07:15:18 PDT 2013


The SpiceSmartcardManager is a singleton, so it does not make
a lot of sense to try to init it multiple times. This commit adds
a GOnce to ensure the manager is only init'ed once.
---
 gtk/smartcard-manager.c | 46 +++++++++++++++++++++++++++++-----------------
 1 file changed, 29 insertions(+), 17 deletions(-)

diff --git a/gtk/smartcard-manager.c b/gtk/smartcard-manager.c
index 2a0e397..683a47e 100644
--- a/gtk/smartcard-manager.c
+++ b/gtk/smartcard-manager.c
@@ -402,9 +402,13 @@ spice_smartcard_manager_update_monitor(void)
 
 #define SPICE_SOFTWARE_READER_NAME "Spice Software Smartcard"
 
-static gboolean smartcard_manager_init(SpiceSession *session,
-                                       GCancellable *cancellable,
-                                       GError **err)
+typedef struct {
+    SpiceSession *session;
+    GCancellable *cancellable;
+    GError *err;
+} SmartcardManagerInitArgs;
+
+static gboolean smartcard_manager_init(SmartcardManagerInitArgs *args)
 {
     gchar *emul_args = NULL;
     VCardEmulOptions *options = NULL;
@@ -414,8 +418,8 @@ static gboolean smartcard_manager_init(SpiceSession *session,
     gboolean retval = FALSE;
 
     SPICE_DEBUG("smartcard_manager_init");
-    g_return_val_if_fail(SPICE_IS_SESSION(session), FALSE);
-    g_object_get(G_OBJECT(session),
+    g_return_val_if_fail(SPICE_IS_SESSION(args->session), FALSE);
+    g_object_get(G_OBJECT(args->session),
                  "smartcard-db", &dbname,
                  "smartcard-certificates", &certificates,
                  NULL);
@@ -438,13 +442,13 @@ static gboolean smartcard_manager_init(SpiceSession *session,
 
     options = vcard_emul_options(emul_args);
     if (options == NULL) {
-        *err = g_error_new(SPICE_CLIENT_ERROR,
-                           SPICE_CLIENT_ERROR_FAILED,
-                           "vcard_emul_options() failed!");
+        args->err = g_error_new(SPICE_CLIENT_ERROR,
+                                SPICE_CLIENT_ERROR_FAILED,
+                                "vcard_emul_options() failed!");
         goto end;
     }
 
-    if (g_cancellable_set_error_if_cancelled(cancellable, err))
+    if (g_cancellable_set_error_if_cancelled(args->cancellable, &args->err))
         goto end;
 
 init:
@@ -452,9 +456,9 @@ init:
     emul_init_status = vcard_emul_init(options);
     if ((emul_init_status != VCARD_EMUL_OK)
             && (emul_init_status != VCARD_EMUL_INIT_ALREADY_INITED)) {
-        *err = g_error_new(SPICE_CLIENT_ERROR,
-                           SPICE_CLIENT_ERROR_FAILED,
-                           "Failed to initialize smartcard");
+        args->err = g_error_new(SPICE_CLIENT_ERROR,
+                                SPICE_CLIENT_ERROR_FAILED,
+                                "Failed to initialize smartcard");
         goto end;
     }
 
@@ -472,12 +476,20 @@ static void smartcard_manager_init_helper(GSimpleAsyncResult *res,
                                           GObject *object,
                                           GCancellable *cancellable)
 {
-    SpiceSession *session = SPICE_SESSION(object);
-    GError *err = NULL;
+    static GOnce smartcard_manager_once = G_ONCE_INIT;
+    SmartcardManagerInitArgs args;
+
+    args.session = SPICE_SESSION(object);
+    args.cancellable = cancellable;
+    args.err = NULL;
+
 
-    if (!smartcard_manager_init(session, cancellable, &err)) {
-        g_simple_async_result_set_from_error(res, err);
-        g_error_free(err);
+    g_once(&smartcard_manager_once,
+           (GThreadFunc)smartcard_manager_init,
+           &args);
+    if (args.err != NULL) {
+        g_simple_async_result_set_from_error(res, args.err);
+        g_error_free(args.err);
     }
 }
 
-- 
1.8.3.1



More information about the Spice-devel mailing list