[evolution-data-server] ECalBackendClass: Add a 'use_serial_dispatch_queue' option.
- From: Matthew Barnes <mbarnes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] ECalBackendClass: Add a 'use_serial_dispatch_queue' option.
- Date: Tue, 2 Apr 2013 19:04:31 +0000 (UTC)
commit 8a56d5e838982824015d9e08b2f9863fc5b2b6b9
Author: Matthew Barnes <mbarnes redhat com>
Date: Tue Apr 2 14:25:48 2013 -0400
ECalBackendClass: Add a 'use_serial_dispatch_queue' option.
ECalBackend 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
ECalBackend subclasses avoid thread-safety issues.
calendar/libedata-cal/e-cal-backend.c | 56 ++++++++++++++++++++++++++++-----
calendar/libedata-cal/e-cal-backend.h | 7 ++++
2 files changed, 55 insertions(+), 8 deletions(-)
---
diff --git a/calendar/libedata-cal/e-cal-backend.c b/calendar/libedata-cal/e-cal-backend.c
index 5087a53..fa56745 100644
--- a/calendar/libedata-cal/e-cal-backend.c
+++ b/calendar/libedata-cal/e-cal-backend.c
@@ -202,6 +202,10 @@ cal_backend_push_operation (ECalBackend *backend,
if (G_IS_CANCELLABLE (cancellable))
node->cancellable = g_object_ref (cancellable);
+ /* All operations block when using a serial dispatch queue. */
+ if (E_CAL_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);
@@ -268,6 +272,23 @@ cal_backend_dispatch_next_operation (ECalBackend *backend)
return TRUE;
}
+static void
+cal_backend_unblock_operations (ECalBackend *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 (cal_backend_dispatch_next_operation (backend))
+ ;
+}
+
static guint32
cal_backend_stash_operation (ECalBackend *backend,
GSimpleAsyncResult *simple)
@@ -1405,14 +1426,7 @@ e_cal_backend_open_finish (ECalBackend *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 (cal_backend_dispatch_next_operation (backend))
- ;
+ cal_backend_unblock_operations (backend, simple);
/* Assume success unless a GError is set. */
return !g_simple_async_result_propagate_error (simple, error);
@@ -1580,6 +1594,8 @@ e_cal_backend_refresh_finish (ECalBackend *backend,
simple = G_SIMPLE_ASYNC_RESULT (result);
+ cal_backend_unblock_operations (backend, simple);
+
/* Assume success unless a GError is set. */
return !g_simple_async_result_propagate_error (simple, error);
}
@@ -1763,6 +1779,8 @@ e_cal_backend_get_object_finish (ECalBackend *backend,
simple = G_SIMPLE_ASYNC_RESULT (result);
async_context = g_simple_async_result_get_op_res_gpointer (simple);
+ cal_backend_unblock_operations (backend, simple);
+
if (g_simple_async_result_propagate_error (simple, error))
return FALSE;
@@ -1956,6 +1974,8 @@ e_cal_backend_get_object_list_finish (ECalBackend *backend,
simple = G_SIMPLE_ASYNC_RESULT (result);
async_context = g_simple_async_result_get_op_res_gpointer (simple);
+ cal_backend_unblock_operations (backend, simple);
+
if (g_simple_async_result_propagate_error (simple, error))
return FALSE;
@@ -2154,6 +2174,8 @@ e_cal_backend_get_free_busy_finish (ECalBackend *backend,
simple = G_SIMPLE_ASYNC_RESULT (result);
+ cal_backend_unblock_operations (backend, simple);
+
/* Assume success unless a GError is set. */
return !g_simple_async_result_propagate_error (simple, error);
}
@@ -2349,6 +2371,8 @@ e_cal_backend_create_objects_finish (ECalBackend *backend,
simple = G_SIMPLE_ASYNC_RESULT (result);
async_context = g_simple_async_result_get_op_res_gpointer (simple);
+ cal_backend_unblock_operations (backend, simple);
+
if (g_simple_async_result_propagate_error (simple, error))
return FALSE;
@@ -2568,6 +2592,8 @@ e_cal_backend_modify_objects_finish (ECalBackend *backend,
simple = G_SIMPLE_ASYNC_RESULT (result);
async_context = g_simple_async_result_get_op_res_gpointer (simple);
+ cal_backend_unblock_operations (backend, simple);
+
if (g_simple_async_result_propagate_error (simple, error))
return FALSE;
@@ -2794,6 +2820,8 @@ e_cal_backend_remove_objects_finish (ECalBackend *backend,
simple = G_SIMPLE_ASYNC_RESULT (result);
async_context = g_simple_async_result_get_op_res_gpointer (simple);
+ cal_backend_unblock_operations (backend, simple);
+
if (g_simple_async_result_propagate_error (simple, error))
return FALSE;
@@ -3014,6 +3042,8 @@ e_cal_backend_receive_objects_finish (ECalBackend *backend,
simple = G_SIMPLE_ASYNC_RESULT (result);
+ cal_backend_unblock_operations (backend, simple);
+
/* Assume success unless a GError is set. */
return !g_simple_async_result_propagate_error (simple, error);
}
@@ -3202,6 +3232,8 @@ e_cal_backend_send_objects_finish (ECalBackend *backend,
simple = G_SIMPLE_ASYNC_RESULT (result);
async_context = g_simple_async_result_get_op_res_gpointer (simple);
+ cal_backend_unblock_operations (backend, simple);
+
if (g_simple_async_result_propagate_error (simple, error))
return NULL;
@@ -3401,6 +3433,8 @@ e_cal_backend_get_attachment_uris_finish (ECalBackend *backend,
simple = G_SIMPLE_ASYNC_RESULT (result);
async_context = g_simple_async_result_get_op_res_gpointer (simple);
+ cal_backend_unblock_operations (backend, simple);
+
if (g_simple_async_result_propagate_error (simple, error))
return FALSE;
@@ -3598,6 +3632,8 @@ e_cal_backend_discard_alarm_finish (ECalBackend *backend,
simple = G_SIMPLE_ASYNC_RESULT (result);
+ cal_backend_unblock_operations (backend, simple);
+
/* Assume success unless a GError is set. */
return !g_simple_async_result_propagate_error (simple, error);
}
@@ -3772,6 +3808,8 @@ e_cal_backend_get_timezone_finish (ECalBackend *backend,
simple = G_SIMPLE_ASYNC_RESULT (result);
async_context = g_simple_async_result_get_op_res_gpointer (simple);
+ cal_backend_unblock_operations (backend, simple);
+
if (g_simple_async_result_propagate_error (simple, error))
return FALSE;
@@ -3947,6 +3985,8 @@ e_cal_backend_add_timezone_finish (ECalBackend *backend,
simple = G_SIMPLE_ASYNC_RESULT (result);
+ cal_backend_unblock_operations (backend, simple);
+
/* Assume success unless a GError is set. */
return !g_simple_async_result_propagate_error (simple, error);
}
diff --git a/calendar/libedata-cal/e-cal-backend.h b/calendar/libedata-cal/e-cal-backend.h
index 304d27f..5e8dc2f 100644
--- a/calendar/libedata-cal/e-cal-backend.h
+++ b/calendar/libedata-cal/e-cal-backend.h
@@ -110,6 +110,13 @@ struct _ECalBackend {
struct _ECalBackendClass {
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) (ECalBackend *backend,
const gchar *prop_name);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]