There was a problem when the main loop wasn't being run for periods of
authorStefan Walter <stefw@src.gnome.org>
Wed, 17 Dec 2008 19:55:48 +0000 (19:55 +0000)
committerStefan Walter <stefw@src.gnome.org>
Wed, 17 Dec 2008 19:55:48 +0000 (19:55 +0000)
* gp11/gp11-call.c: There was a problem when the main loop
wasn't being run for periods of time, things would backup.
Now we process a result for every async call we make.

* gp11/gp11-object.c:
* gp11/gp11-slot.c: Object lifetime fixes.

svn path=/trunk/; revision=1392

gp11/gp11-call.c
gp11/gp11-object.c
gp11/gp11-slot.c

index 35ddd96..26597ea 100644 (file)
@@ -139,6 +139,23 @@ process_result (GP11Call *call, gpointer unused)
 }
 
 static gboolean
+process_completed (void)
+{
+       gpointer call;
+
+       g_assert (completed_queue);
+
+       call = g_async_queue_try_pop (completed_queue);
+       if (call) {
+               process_result (call, NULL);
+               g_object_unref (call);
+               return TRUE;
+       }
+
+       return FALSE;
+}
+
+static gboolean
 completed_prepare(GSource* source, gint *timeout)
 {
        gboolean have;
@@ -158,17 +175,7 @@ completed_check(GSource* source)
 static gboolean
 completed_dispatch(GSource* source, GSourceFunc callback, gpointer user_data)
 {
-       gpointer *call;
-
-       g_assert (completed_queue);
-       g_assert (callback);
-
-       call = g_async_queue_try_pop (completed_queue);
-       if (call) {
-               ((GFunc)callback) (call, user_data);
-               g_object_unref (call);
-       }
-
+       process_completed ();
        return TRUE;
 }
 
@@ -253,7 +260,7 @@ _gp11_call_class_init (GP11CallClass *klass)
        gobject_class->finalize = _gp11_call_finalize;
 
        g_assert (!thread_pool);
-       thread_pool = g_thread_pool_new ((GFunc)process_async_call, NULL, -1, FALSE, &err);
+       thread_pool = g_thread_pool_new ((GFunc)process_async_call, NULL, 16, FALSE, &err);
        if (!thread_pool) {
                g_critical ("couldn't create thread pool: %s",
                            err && err->message ? err->message : "");
@@ -271,7 +278,7 @@ _gp11_call_class_init (GP11CallClass *klass)
        g_assert (!completed_id);
        src = g_source_new (&completed_functions, sizeof (GSource));
        completed_id = g_source_attach (src, context);
-       g_source_set_callback (src, (GSourceFunc)process_result, NULL, NULL);
+       g_source_set_callback (src, NULL, NULL, NULL);
        g_source_unref (src);
 }
 
@@ -430,6 +437,9 @@ _gp11_call_async_go (GP11Call *call)
        g_assert (GP11_IS_CALL (call));
        g_assert (call->args->pkcs11);
 
+       /* To keep things balanced, process at one completed event */
+       process_completed();
+
        g_assert (thread_pool);
        g_thread_pool_push (thread_pool, call, NULL);
 }
index 9212914..1f7eeb6 100644 (file)
@@ -49,7 +49,8 @@ run_call_with_session (GP11Call *call, GP11Session *session)
        g_assert (GP11_IS_SESSION (session));
 
        /* Hold onto this session for the length of the call */
-       g_object_set_data_full (G_OBJECT (call), "call-opened-session", session, g_object_unref);
+       g_object_set_data_full (G_OBJECT (call), "call-opened-session",
+                               g_object_ref (session), g_object_unref);
 
        _gp11_call_async_object (call, session);
        _gp11_call_async_go (call);
@@ -71,9 +72,11 @@ opened_session (GObject *obj, GAsyncResult *result, gpointer user_data)
        if (!session) {
                _gp11_call_async_short (user_data, err->code);
                g_error_free (err);
+               return;
        }
 
        run_call_with_session (GP11_CALL (user_data), session);
+       g_object_unref (session);
 }
 
 static void
index ff18840..44518a8 100644 (file)
@@ -200,6 +200,8 @@ pop_session_table (GP11Slot *slot, gulong flags)
        result = g_array_index (pool->sessions, CK_SESSION_HANDLE, pool->sessions->len - 1);
        g_assert (result != 0);
        g_array_remove_index_fast (pool->sessions, pool->sessions->len - 1);
+       if (!pool->sessions->len)
+               g_hash_table_remove(pv->open_sessions, &flags);
 
        return result;
 }
@@ -272,12 +274,15 @@ reuse_session_handle (GP11Session *session, GP11Slot *slot)
         */
        flags = g_object_get_data (G_OBJECT (session), "gp11-open-session-flags");
        g_return_if_fail (flags);
-       if ((*flags & info.flags) != *flags)
+       if ((*flags & info.flags) != *flags) {
+g_message ("discarding session, wrong flags");
                return;
+       }
 
        /* Keep this one around for later use */
        push_session_table (slot, *flags, session->handle);
        session->handle = 0;
+g_message ("keeping the session for reuse");
 }
 
 static GP11Session*