[evolution-data-server] EBookBackendClass: Add a 'use_serial_dispatch_queue' option.
- From: Matthew Barnes <mbarnes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] EBookBackendClass: Add a 'use_serial_dispatch_queue' option.
- Date: Tue, 2 Apr 2013 19:04:26 +0000 (UTC)
commit 0def22dd549d807dac6e4faac0996f788e90ae74
Author: Matthew Barnes <mbarnes redhat com>
Date: Tue Apr 2 12:42:34 2013 -0400
EBookBackendClass: Add a 'use_serial_dispatch_queue' option.
EBookBackend subclasses can set this to TRUE to use a serial dispatch
queue, instead of a concurrent dispatch queue. A serial dispatch queue
executes one method at a time in the order in which methods were called.
This is generally slower than a concurrent dispatch queue, but can help
EBookBackend subclasses avoid thread-safety issues.
addressbook/libedata-book/e-book-backend.c | 44 ++++++++++++++++++++++-----
addressbook/libedata-book/e-book-backend.h | 7 ++++
2 files changed, 43 insertions(+), 8 deletions(-)
---
diff --git a/addressbook/libedata-book/e-book-backend.c b/addressbook/libedata-book/e-book-backend.c
index eed1b5a..ab33708 100644
--- a/addressbook/libedata-book/e-book-backend.c
+++ b/addressbook/libedata-book/e-book-backend.c
@@ -144,6 +144,10 @@ 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);
@@ -210,6 +214,23 @@ book_backend_dispatch_next_operation (EBookBackend *backend)
return TRUE;
}
+static void
+book_backend_unblock_operations (EBookBackend *backend,
+ GSimpleAsyncResult *simple)
+{
+ /* If the GSimpleAsyncResult was blocking the dispatch queue,
+ * unblock the dispatch queue. Then dispatch as many waiting
+ * operations as we can. */
+
+ g_mutex_lock (&backend->priv->operation_lock);
+ if (backend->priv->blocked == simple)
+ g_clear_object (&backend->priv->blocked);
+ g_mutex_unlock (&backend->priv->operation_lock);
+
+ while (book_backend_dispatch_next_operation (backend))
+ ;
+}
+
static guint32
book_backend_stash_operation (EBookBackend *backend,
GSimpleAsyncResult *simple)
@@ -907,14 +928,7 @@ e_book_backend_open_finish (EBookBackend *backend,
simple = G_SIMPLE_ASYNC_RESULT (result);
- /* This operation blocks, so we need to let waiting operations
- * through. (FIXME Centralize this for any blocking operation.) */
- g_mutex_lock (&backend->priv->operation_lock);
- if (backend->priv->blocked == simple)
- g_clear_object (&backend->priv->blocked);
- g_mutex_unlock (&backend->priv->operation_lock);
- while (book_backend_dispatch_next_operation (backend))
- ;
+ book_backend_unblock_operations (backend, simple);
/* Assume success unless a GError is set. */
return !g_simple_async_result_propagate_error (simple, error);
@@ -1082,6 +1096,8 @@ e_book_backend_refresh_finish (EBookBackend *backend,
simple = G_SIMPLE_ASYNC_RESULT (result);
+ book_backend_unblock_operations (backend, simple);
+
/* Assume success unless a GError is set. */
return !g_simple_async_result_propagate_error (simple, error);
}
@@ -1273,6 +1289,8 @@ e_book_backend_create_contacts_finish (EBookBackend *backend,
simple = G_SIMPLE_ASYNC_RESULT (result);
async_context = g_simple_async_result_get_op_res_gpointer (simple);
+ book_backend_unblock_operations (backend, simple);
+
if (g_simple_async_result_propagate_error (simple, error))
return FALSE;
@@ -1459,6 +1477,8 @@ e_book_backend_modify_contacts_finish (EBookBackend *backend,
simple = G_SIMPLE_ASYNC_RESULT (result);
async_context = g_simple_async_result_get_op_res_gpointer (simple);
+ book_backend_unblock_operations (backend, simple);
+
if (g_simple_async_result_propagate_error (simple, error))
return FALSE;
@@ -1647,6 +1667,8 @@ e_book_backend_remove_contacts_finish (EBookBackend *backend,
simple = G_SIMPLE_ASYNC_RESULT (result);
async_context = g_simple_async_result_get_op_res_gpointer (simple);
+ book_backend_unblock_operations (backend, simple);
+
if (g_simple_async_result_propagate_error (simple, error))
return FALSE;
@@ -1837,6 +1859,8 @@ e_book_backend_get_contact_finish (EBookBackend *backend,
simple = G_SIMPLE_ASYNC_RESULT (result);
async_context = g_simple_async_result_get_op_res_gpointer (simple);
+ book_backend_unblock_operations (backend, simple);
+
if (g_simple_async_result_propagate_error (simple, error))
return NULL;
@@ -2032,6 +2056,8 @@ e_book_backend_get_contact_list_finish (EBookBackend *backend,
simple = G_SIMPLE_ASYNC_RESULT (result);
async_context = g_simple_async_result_get_op_res_gpointer (simple);
+ book_backend_unblock_operations (backend, simple);
+
if (g_simple_async_result_propagate_error (simple, error))
return FALSE;
@@ -2224,6 +2250,8 @@ e_book_backend_get_contact_list_uids_finish (EBookBackend *backend,
simple = G_SIMPLE_ASYNC_RESULT (result);
async_context = g_simple_async_result_get_op_res_gpointer (simple);
+ book_backend_unblock_operations (backend, simple);
+
if (g_simple_async_result_propagate_error (simple, error))
return FALSE;
diff --git a/addressbook/libedata-book/e-book-backend.h b/addressbook/libedata-book/e-book-backend.h
index bd9e3c9..8a6796a 100644
--- a/addressbook/libedata-book/e-book-backend.h
+++ b/addressbook/libedata-book/e-book-backend.h
@@ -101,6 +101,13 @@ struct _EBookBackend {
struct _EBookBackendClass {
EBackendClass parent_class;
+ /* Set this to TRUE to use a serial dispatch queue, instead
+ * of a concurrent dispatch queue. A serial dispatch queue
+ * executes one method at a time in the order in which they
+ * were called. This is generally slower than a concurrent
+ * dispatch queue, but helps avoid thread-safety issues. */
+ gboolean use_serial_dispatch_queue;
+
/* Virtual methods */
gchar * (*get_backend_property) (EBookBackend *backend,
const gchar *prop_name);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]