[evolution-data-server] EBookBackend: Use GThreadPool instead of g_io_scheduler_push_job().



commit 0855968db4f2533b9712d57c98688930a0875e0f
Author: Matthew Barnes <mbarnes redhat com>
Date:   Sat Nov 23 10:55:59 2013 -0500

    EBookBackend: Use GThreadPool instead of g_io_scheduler_push_job().
    
    Once the old-style backend API is gone we can port everything to GTask,
    but for now be conservative with the changes.

 addressbook/libedata-book/e-book-backend.c |   49 +++++++++++++++++----------
 1 files changed, 31 insertions(+), 18 deletions(-)
---
diff --git a/addressbook/libedata-book/e-book-backend.c b/addressbook/libedata-book/e-book-backend.c
index 4033f99..ce5afc3 100644
--- a/addressbook/libedata-book/e-book-backend.c
+++ b/addressbook/libedata-book/e-book-backend.c
@@ -55,6 +55,7 @@ struct _EBookBackendPrivate {
        gulong auth_source_changed_handler_id;
 
        GMutex operation_lock;
+       GThreadPool *thread_pool;
        GHashTable *operation_ids;
        GQueue pending_operations;
        guint32 next_operation_id;
@@ -163,25 +164,19 @@ book_backend_push_operation (EBookBackend *backend,
        if (G_IS_CANCELLABLE (cancellable))
                node->cancellable = g_object_ref (cancellable);
 
-       /* All operations block when using a serial dispatch queue. */
-       if (E_BOOK_BACKEND_GET_CLASS (backend)->use_serial_dispatch_queue)
-               node->blocking_operation = TRUE;
-
        g_queue_push_tail (&backend->priv->pending_operations, node);
 
        g_mutex_unlock (&backend->priv->operation_lock);
 }
 
-static gboolean
-book_backend_dispatch_thread (GIOSchedulerJob *job,
-                              GCancellable *cancellable,
-                              gpointer user_data)
+static void
+book_backend_dispatch_thread (DispatchNode *node)
 {
-       DispatchNode *node = user_data;
-       GError *error = NULL;
+       GCancellable *cancellable = node->cancellable;
+       GError *local_error = NULL;
 
-       if (g_cancellable_set_error_if_cancelled (cancellable, &error)) {
-               g_simple_async_result_take_error (node->simple, error);
+       if (g_cancellable_set_error_if_cancelled (cancellable, &local_error)) {
+               g_simple_async_result_take_error (node->simple, local_error);
                g_simple_async_result_complete_in_idle (node->simple);
        } else {
                GAsyncResult *result;
@@ -193,7 +188,7 @@ book_backend_dispatch_thread (GIOSchedulerJob *job,
                g_object_unref (source_object);
        }
 
-       return FALSE;
+       dispatch_node_free (node);
 }
 
 static gboolean
@@ -224,11 +219,9 @@ book_backend_dispatch_next_operation (EBookBackend *backend)
 
        g_mutex_unlock (&backend->priv->operation_lock);
 
-       g_io_scheduler_push_job (
-               book_backend_dispatch_thread,
-               node, (GDestroyNotify) dispatch_node_free,
-               G_PRIORITY_DEFAULT,
-               node->cancellable);
+       /* An error here merely indicates a thread could not be
+        * created, and so the node was queued.  We don't care. */
+       g_thread_pool_push (backend->priv->thread_pool, node, NULL);
 
        return TRUE;
 }
@@ -509,6 +502,9 @@ book_backend_finalize (GObject *object)
        g_mutex_clear (&priv->operation_lock);
        g_hash_table_destroy (priv->operation_ids);
 
+       /* Return immediately, do not wait. */
+       g_thread_pool_free (priv->thread_pool, TRUE, FALSE);
+
        /* Chain up to parent's finalize() method. */
        G_OBJECT_CLASS (e_book_backend_parent_class)->finalize (object);
 }
@@ -519,6 +515,8 @@ book_backend_constructed (GObject *object)
        EBookBackend *backend;
        ESourceRegistry *registry;
        ESource *source;
+       gint max_threads = -1;
+       gboolean exclusive = FALSE;
 
        /* Chain up to parent's constructed() method. */
        G_OBJECT_CLASS (e_book_backend_parent_class)->constructed (object);
@@ -527,6 +525,21 @@ book_backend_constructed (GObject *object)
        registry = e_book_backend_get_registry (backend);
        source = e_backend_get_source (E_BACKEND (backend));
 
+       /* If the backend specifies a serial dispatch queue, create
+        * a thread pool with one exclusive thread.  The thread pool
+        * will serialize operations for us. */
+       if (E_BOOK_BACKEND_GET_CLASS (backend)->use_serial_dispatch_queue) {
+               max_threads = 1;
+               exclusive = TRUE;
+       }
+
+       /* XXX If creating an exclusive thread pool, technically there's
+        *     a small chance of error here but we'll risk it since it's
+        *     only for one exclusive thread. */
+       backend->priv->thread_pool = g_thread_pool_new (
+               (GFunc) book_backend_dispatch_thread,
+               NULL, max_threads, exclusive, NULL);
+
        /* Initialize the "cache-dir" property. */
        book_backend_set_default_cache_dir (backend);
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]