[evolution-data-server] CamelTransport: Stop using the internal 'send_lock'.
- From: Matthew Barnes <mbarnes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] CamelTransport: Stop using the internal 'send_lock'.
- Date: Thu, 5 Dec 2013 14:40:23 +0000 (UTC)
commit 9e84126161c814f20a5b2fc91415673689563b2d
Author: Matthew Barnes <mbarnes redhat com>
Date: Thu Dec 5 09:26:44 2013 -0500
CamelTransport: Stop using the internal 'send_lock'.
Use camel_service_queue_task() instead of locking an internal mutex.
This ensures methods are run in the order they were called, and also
makes cancellation of a waiting method immediate instead of blocking
until it acquires the mutex it's competing for.
This requires flip-flopping the synchronous and asynchronous functions,
so that the synchronous function calls its asynchronous counterpart with
help from CamelAsyncClosure.
camel/camel-transport.c | 65 +++++++++++++++++++---------------------------
1 files changed, 27 insertions(+), 38 deletions(-)
---
diff --git a/camel/camel-transport.c b/camel/camel-transport.c
index 4f0b68e..856aef8 100644
--- a/camel/camel-transport.c
+++ b/camel/camel-transport.c
@@ -28,6 +28,7 @@
#endif
#include "camel-address.h"
+#include "camel-async-closure.h"
#include "camel-debug.h"
#include "camel-mime-message.h"
#include "camel-transport.h"
@@ -39,11 +40,10 @@
typedef struct _AsyncContext AsyncContext;
struct _CamelTransportPrivate {
- GMutex send_lock; /* for locking send operations */
+ gint placeholder;
};
struct _AsyncContext {
- /* arguments */
CamelAddress *from;
CamelAddress *recipients;
CamelMimeMessage *message;
@@ -67,35 +67,15 @@ async_context_free (AsyncContext *async_context)
}
static void
-transport_finalize (GObject *object)
-{
- CamelTransportPrivate *priv;
-
- priv = CAMEL_TRANSPORT_GET_PRIVATE (object);
-
- g_mutex_clear (&priv->send_lock);
-
- /* Chain up to parent's finalize() method. */
- G_OBJECT_CLASS (camel_transport_parent_class)->finalize (object);
-}
-
-static void
camel_transport_class_init (CamelTransportClass *class)
{
- GObjectClass *object_class;
-
g_type_class_add_private (class, sizeof (CamelTransportPrivate));
-
- object_class = G_OBJECT_CLASS (class);
- object_class->finalize = transport_finalize;
}
static void
camel_transport_init (CamelTransport *transport)
{
transport->priv = CAMEL_TRANSPORT_GET_PRIVATE (transport);
-
- g_mutex_init (&transport->priv->send_lock);
}
/**
@@ -123,7 +103,8 @@ camel_transport_send_to_sync (CamelTransport *transport,
GCancellable *cancellable,
GError **error)
{
- CamelTransportClass *class;
+ CamelAsyncClosure *closure;
+ GAsyncResult *result;
gboolean success;
g_return_val_if_fail (CAMEL_IS_TRANSPORT (transport), FALSE);
@@ -131,22 +112,18 @@ camel_transport_send_to_sync (CamelTransport *transport,
g_return_val_if_fail (CAMEL_IS_ADDRESS (from), FALSE);
g_return_val_if_fail (CAMEL_IS_ADDRESS (recipients), FALSE);
- class = CAMEL_TRANSPORT_GET_CLASS (transport);
- g_return_val_if_fail (class->send_to_sync != NULL, FALSE);
+ closure = camel_async_closure_new ();
- g_mutex_lock (&transport->priv->send_lock);
+ camel_transport_send_to (
+ transport, message, from, recipients,
+ G_PRIORITY_DEFAULT, cancellable,
+ camel_async_closure_callback, closure);
- /* Check for cancellation after locking. */
- if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
- g_mutex_unlock (&transport->priv->send_lock);
- return FALSE;
- }
+ result = camel_async_closure_wait (closure);
- success = class->send_to_sync (
- transport, message, from, recipients, cancellable, error);
- CAMEL_CHECK_GERROR (transport, send_to_sync, success, error);
+ success = camel_transport_send_to_finish (transport, result, error);
- g_mutex_unlock (&transport->priv->send_lock);
+ camel_async_closure_free (closure);
return success;
}
@@ -158,18 +135,26 @@ transport_send_to_thread (GTask *task,
gpointer task_data,
GCancellable *cancellable)
{
- gboolean success;
+ CamelTransport *transport;
+ CamelTransportClass *class;
AsyncContext *async_context;
+ gboolean success;
GError *local_error = NULL;
+ transport = CAMEL_TRANSPORT (source_object);
async_context = (AsyncContext *) task_data;
- success = camel_transport_send_to_sync (
+ class = CAMEL_TRANSPORT_GET_CLASS (transport);
+ g_return_if_fail (class->send_to_sync != NULL);
+
+ success = class->send_to_sync (
CAMEL_TRANSPORT (source_object),
async_context->message,
async_context->from,
async_context->recipients,
cancellable, &local_error);
+ CAMEL_CHECK_LOCAL_GERROR (
+ transport, send_to_sync, success, local_error);
if (local_error != NULL) {
g_task_return_error (task, local_error);
@@ -209,6 +194,7 @@ camel_transport_send_to (CamelTransport *transport,
gpointer user_data)
{
GTask *task;
+ CamelService *service;
AsyncContext *async_context;
g_return_if_fail (CAMEL_IS_TRANSPORT (transport));
@@ -216,6 +202,8 @@ camel_transport_send_to (CamelTransport *transport,
g_return_if_fail (CAMEL_IS_ADDRESS (from));
g_return_if_fail (CAMEL_IS_ADDRESS (recipients));
+ service = CAMEL_SERVICE (transport);
+
async_context = g_slice_new0 (AsyncContext);
async_context->from = g_object_ref (from);
async_context->recipients = g_object_ref (recipients);
@@ -229,7 +217,8 @@ camel_transport_send_to (CamelTransport *transport,
task, async_context,
(GDestroyNotify) async_context_free);
- g_task_run_in_thread (task, transport_send_to_thread);
+ camel_service_queue_task (
+ service, task, transport_send_to_thread);
g_object_unref (task);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]