AuthSession: let the callback unreference "self"
authorAlberto Mardegan <alberto.mardegan@canonical.com>
Tue, 17 Jul 2012 08:48:08 +0000 (11:48 +0300)
committerAlberto Mardegan <alberto.mardegan@canonical.com>
Tue, 17 Jul 2012 08:48:08 +0000 (11:48 +0300)
Keep a reference on "self" while invoking the callback.
This fixes:
http://code.google.com/p/accounts-sso/issues/detail?id=81

libsignon-glib/signon-auth-session.c
tests/check_signon.c

index b2ea06a06fd60770de485669e4000a8de5a04347..837be06256cae257257f9e31b5c4722a7def2a79 100644 (file)
@@ -645,6 +645,9 @@ auth_session_process_reply (DBusGProxy *proxy, GHashTable *session_data,
         session_data = NULL;
     }
 
+    /* Keep a reference on the SignonAuthSession, because the callback
+     * code might unreference it, while we still need it. */
+    g_object_ref (cb_data->self);
     (cb_data->cb)
         (cb_data->self, session_data, new_error, cb_data->user_data);
 
@@ -652,6 +655,7 @@ auth_session_process_reply (DBusGProxy *proxy, GHashTable *session_data,
     if (new_error)
         g_error_free (new_error);
 
+    g_object_unref (cb_data->self);
     g_slice_free (AuthSessionProcessCbData, cb_data);
 }
 
index d4126fbcb0d3a1371eb803db2a232427124f4742..851fe40aa5f067b1fd8f4467e16965af75c35928 100644 (file)
@@ -1168,6 +1168,63 @@ START_TEST(test_unregistered_auth_session)
 }
 END_TEST
 
+static void
+test_regression_unref_process_cb (SignonAuthSession *self,
+                                  GHashTable *reply,
+                                  const GError *error,
+                                  gpointer user_data)
+{
+    GValue *v_string;
+
+    if (error)
+    {
+        g_warning ("%s: %s", G_STRFUNC, error->message);
+        g_main_loop_quit (main_loop);
+        fail();
+    }
+
+    fail_unless (reply != NULL, "The result is empty");
+
+    fail_unless (g_strcmp0 (user_data, "Hi there!") == 0,
+                 "Didn't get expected user_data");
+
+    v_string = g_hash_table_lookup(reply, "James");
+    fail_unless (v_string != 0);
+    fail_unless (g_strcmp0 (g_value_get_string (v_string), "Bond") == 0,
+                 "Wrong reply data");
+
+    /* The next line is actually the regression we want to test */
+    g_object_unref (self);
+
+    g_main_loop_quit (main_loop);
+}
+
+START_TEST(test_regression_unref)
+{
+    SignonAuthSession *auth_session;
+    GHashTable *session_data;
+    GError *error = NULL;
+    GValue v_string = G_VALUE_INIT;
+
+    g_type_init ();
+    main_loop = g_main_loop_new (NULL, FALSE);
+
+    auth_session = signon_auth_session_new (0, "ssotest", &error);
+    fail_unless (auth_session != NULL);
+
+    session_data = g_hash_table_new (g_str_hash, g_str_equal);
+    g_value_init (&v_string, G_TYPE_STRING);
+    g_value_set_static_string (&v_string, "Bond");
+    g_hash_table_insert (session_data, "James", &v_string);
+
+    signon_auth_session_process (auth_session,
+                                 session_data,
+                                 "mech1",
+                                 test_regression_unref_process_cb,
+                                 g_strdup ("Hi there!"));
+    g_main_loop_run (main_loop);
+}
+END_TEST
 
 Suite *
 signon_suite(void)
@@ -1199,6 +1256,9 @@ signon_suite(void)
     tcase_add_test (tc_core, test_signout_identity);
     tcase_add_test (tc_core, test_unregistered_identity);
     tcase_add_test (tc_core, test_unregistered_auth_session);
+
+    tcase_add_test (tc_core, test_regression_unref);
+
     suite_add_tcase (s, tc_core);
 
     return s;