[evolution-data-server] CamelService: Port to GTask.
- From: Matthew Barnes <mbarnes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] CamelService: Port to GTask.
- Date: Tue, 3 Dec 2013 16:45:39 +0000 (UTC)
commit 893bd50f966d5997a2bbbb354f579275e8b84b3d
Author: Matthew Barnes <mbarnes redhat com>
Date: Tue Dec 3 11:05:24 2013 -0500
CamelService: Port to GTask.
camel/camel-service.c | 377 ++++++++++++++++++++++++-------------------------
1 files changed, 188 insertions(+), 189 deletions(-)
---
diff --git a/camel/camel-service.c b/camel/camel-service.c
index fc52237..269aeda 100644
--- a/camel/camel-service.c
+++ b/camel/camel-service.c
@@ -78,9 +78,8 @@ struct _CamelServicePrivate {
};
struct _AsyncContext {
- GList *auth_types;
gchar *auth_mechanism;
- CamelAuthenticationResult auth_result;
+ gboolean clean;
};
/* The GQueue is only modified while CamelService's
@@ -89,8 +88,8 @@ struct _AsyncContext {
struct _ConnectionOp {
volatile gint ref_count;
GQueue pending;
- GMutex simple_lock;
- GSimpleAsyncResult *simple;
+ GMutex task_lock;
+ GTask *task;
GCancellable *cancellable;
gulong cancel_id;
};
@@ -118,23 +117,21 @@ G_DEFINE_ABSTRACT_TYPE_WITH_CODE (
static void
async_context_free (AsyncContext *async_context)
{
- g_list_free (async_context->auth_types);
-
g_free (async_context->auth_mechanism);
g_slice_free (AsyncContext, async_context);
}
static ConnectionOp *
-connection_op_new (GSimpleAsyncResult *simple,
+connection_op_new (GTask *task,
GCancellable *cancellable)
{
ConnectionOp *op;
op = g_slice_new0 (ConnectionOp);
op->ref_count = 1;
- g_mutex_init (&op->simple_lock);
- op->simple = g_object_ref (simple);
+ g_mutex_init (&op->task_lock);
+ op->task = g_object_ref (task);
if (G_IS_CANCELLABLE (cancellable))
op->cancellable = g_object_ref (cancellable);
@@ -164,10 +161,10 @@ connection_op_unref (ConnectionOp *op)
/* The pending queue should be empty. */
g_warn_if_fail (g_queue_is_empty (&op->pending));
- g_mutex_clear (&op->simple_lock);
+ g_mutex_clear (&op->task_lock);
- if (op->simple != NULL)
- g_object_unref (op->simple);
+ if (op->task != NULL)
+ g_object_unref (op->task);
if (op->cancel_id > 0)
g_cancellable_disconnect (
@@ -184,39 +181,45 @@ static void
connection_op_complete (ConnectionOp *op,
const GError *error)
{
- g_mutex_lock (&op->simple_lock);
+ g_mutex_lock (&op->task_lock);
- if (op->simple != NULL && error != NULL)
- g_simple_async_result_set_from_error (op->simple, error);
+ if (op->task != NULL) {
+ if (error != NULL) {
+ g_task_return_error (op->task, g_error_copy (error));
+ } else {
+ g_task_return_boolean (op->task, TRUE);
+ }
- if (op->simple != NULL) {
- g_simple_async_result_complete_in_idle (op->simple);
- g_object_unref (op->simple);
- op->simple = NULL;
+ g_clear_object (&op->task);
}
- g_mutex_unlock (&op->simple_lock);
+ g_mutex_unlock (&op->task_lock);
}
static void
connection_op_cancelled (GCancellable *cancellable,
ConnectionOp *op)
{
- /* Because we called g_simple_async_result_set_check_cancellable()
- * we don't need to explicitly set a G_IO_ERROR_CANCELLED here. */
- connection_op_complete (op, NULL);
+ /* A cancelled GTask will always propagate an error, so we
+ * don't need to explicitly set a G_IO_ERROR_CANCELLED here. */
+
+ g_mutex_lock (&op->task_lock);
+
+ g_clear_object (&op->task);
+
+ g_mutex_unlock (&op->task_lock);
}
static void
connection_op_add_pending (ConnectionOp *op,
- GSimpleAsyncResult *simple,
+ GTask *task,
GCancellable *cancellable)
{
ConnectionOp *pending_op;
g_return_if_fail (op != NULL);
- pending_op = connection_op_new (simple, cancellable);
+ pending_op = connection_op_new (task, cancellable);
if (pending_op->cancellable != NULL)
pending_op->cancel_id = g_cancellable_connect (
@@ -363,16 +366,12 @@ service_shared_connect_cb (GObject *source_object,
gpointer user_data)
{
CamelService *service;
- GSimpleAsyncResult *simple;
ConnectionOp *op = user_data;
- gboolean success = TRUE;
- GError *error = NULL;
+ gboolean success;
+ GError *local_error = NULL;
service = CAMEL_SERVICE (source_object);
- simple = G_SIMPLE_ASYNC_RESULT (result);
-
- if (g_simple_async_result_propagate_error (simple, &error))
- success = FALSE;
+ success = g_task_propagate_boolean (G_TASK (result), &local_error);
g_mutex_lock (&service->priv->connection_lock);
@@ -386,35 +385,39 @@ service_shared_connect_cb (GObject *source_object,
service_queue_notify_connection_status (service);
}
- connection_op_complete (op, error);
- connection_op_complete_pending (op, error);
+ connection_op_complete (op, local_error);
+ connection_op_complete_pending (op, local_error);
g_mutex_unlock (&service->priv->connection_lock);
connection_op_unref (op);
- g_clear_error (&error);
+ g_clear_error (&local_error);
}
static void
-service_shared_connect_thread (GSimpleAsyncResult *simple,
- GObject *object,
+service_shared_connect_thread (GTask *task,
+ gpointer source_object,
+ gpointer task_data,
GCancellable *cancellable)
{
- CamelService *service;
CamelServiceClass *class;
- GError *error = NULL;
+ gboolean success;
+ GError *local_error = NULL;
/* Note we call the class method directly here. */
- service = CAMEL_SERVICE (object);
-
- class = CAMEL_SERVICE_GET_CLASS (service);
+ class = CAMEL_SERVICE_GET_CLASS (source_object);
g_return_if_fail (class->connect_sync != NULL);
- class->connect_sync (service, cancellable, &error);
+ success = class->connect_sync (
+ CAMEL_SERVICE (source_object),
+ cancellable, &local_error);
- if (error != NULL)
- g_simple_async_result_take_error (simple, error);
+ if (local_error != NULL) {
+ g_task_return_error (task, local_error);
+ } else {
+ g_task_return_boolean (task, success);
+ }
}
static void
@@ -422,19 +425,19 @@ service_shared_connect (CamelService *service,
gint io_priority,
ConnectionOp *op)
{
- GSimpleAsyncResult *simple;
+ GTask *task;
- simple = g_simple_async_result_new (
- G_OBJECT (service), service_shared_connect_cb,
- connection_op_ref (op), service_shared_connect);
+ task = g_task_new (
+ service, op->cancellable,
+ service_shared_connect_cb,
+ connection_op_ref (op));
- g_simple_async_result_set_check_cancellable (simple, op->cancellable);
+ g_task_set_source_tag (task, service_shared_connect);
+ g_task_set_priority (task, io_priority);
- g_simple_async_result_run_in_thread (
- simple, service_shared_connect_thread,
- io_priority, op->cancellable);
+ g_task_run_in_thread (task, service_shared_connect_thread);
- g_object_unref (simple);
+ g_object_unref (task);
}
static void
@@ -443,16 +446,12 @@ service_shared_disconnect_cb (GObject *source_object,
gpointer user_data)
{
CamelService *service;
- GSimpleAsyncResult *simple;
ConnectionOp *op = user_data;
- gboolean success = TRUE;
- GError *error = NULL;
+ gboolean success;
+ GError *local_error = NULL;
service = CAMEL_SERVICE (source_object);
- simple = G_SIMPLE_ASYNC_RESULT (result);
-
- if (g_simple_async_result_propagate_error (simple, &error))
- success = FALSE;
+ success = g_task_propagate_boolean (G_TASK (result), &local_error);
g_mutex_lock (&service->priv->connection_lock);
@@ -466,37 +465,43 @@ service_shared_disconnect_cb (GObject *source_object,
service_queue_notify_connection_status (service);
}
- connection_op_complete (op, error);
- connection_op_complete_pending (op, error);
+ connection_op_complete (op, local_error);
+ connection_op_complete_pending (op, local_error);
g_mutex_unlock (&service->priv->connection_lock);
connection_op_unref (op);
- g_clear_error (&error);
+ g_clear_error (&local_error);
}
static void
-service_shared_disconnect_thread (GSimpleAsyncResult *simple,
- GObject *object,
+service_shared_disconnect_thread (GTask *task,
+ gpointer source_object,
+ gpointer task_data,
GCancellable *cancellable)
{
- CamelService *service;
CamelServiceClass *class;
- gboolean clean;
- GError *error = NULL;
+ AsyncContext *async_context;
+ gboolean success;
+ GError *local_error = NULL;
/* Note we call the class method directly here. */
- service = CAMEL_SERVICE (object);
- clean = g_simple_async_result_get_op_res_gboolean (simple);
+ async_context = (AsyncContext *) task_data;
- class = CAMEL_SERVICE_GET_CLASS (service);
+ class = CAMEL_SERVICE_GET_CLASS (source_object);
g_return_if_fail (class->disconnect_sync != NULL);
- class->disconnect_sync (service, clean, cancellable, &error);
+ success = class->disconnect_sync (
+ CAMEL_SERVICE (source_object),
+ async_context->clean,
+ cancellable, &local_error);
- if (error != NULL)
- g_simple_async_result_take_error (simple, error);
+ if (local_error != NULL) {
+ g_task_return_error (task, local_error);
+ } else {
+ g_task_return_boolean (task, success);
+ }
}
static void
@@ -505,21 +510,27 @@ service_shared_disconnect (CamelService *service,
gint io_priority,
ConnectionOp *op)
{
- GSimpleAsyncResult *simple;
+ GTask *task;
+ AsyncContext *async_context;
- simple = g_simple_async_result_new (
- G_OBJECT (service), service_shared_disconnect_cb,
- connection_op_ref (op), service_shared_disconnect);
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->clean = clean;
+
+ task = g_task_new (
+ service, op->cancellable,
+ service_shared_disconnect_cb,
+ connection_op_ref (op));
- g_simple_async_result_set_check_cancellable (simple, op->cancellable);
+ g_task_set_source_tag (task, service_shared_disconnect);
+ g_task_set_priority (task, io_priority);
- g_simple_async_result_set_op_res_gboolean (simple, clean);
+ g_task_set_task_data (
+ task, async_context,
+ (GDestroyNotify) async_context_free);
- g_simple_async_result_run_in_thread (
- simple, service_shared_disconnect_thread,
- io_priority, op->cancellable);
+ g_task_run_in_thread (task, service_shared_disconnect_thread);
- g_object_unref (simple);
+ g_object_unref (task);
}
static void
@@ -1580,17 +1591,14 @@ camel_service_connect (CamelService *service,
GAsyncReadyCallback callback,
gpointer user_data)
{
+ GTask *task;
ConnectionOp *op;
- GSimpleAsyncResult *simple;
g_return_if_fail (CAMEL_IS_SERVICE (service));
- simple = g_simple_async_result_new (
- G_OBJECT (service),
- callback, user_data,
- camel_service_connect);
-
- g_simple_async_result_set_check_cancellable (simple, cancellable);
+ task = g_task_new (service, cancellable, callback, user_data);
+ g_task_set_source_tag (task, camel_service_connect);
+ g_task_set_priority (task, io_priority);
g_mutex_lock (&service->priv->connection_lock);
@@ -1602,12 +1610,12 @@ camel_service_connect (CamelService *service,
case CAMEL_SERVICE_CONNECTING:
connection_op_add_pending (
service->priv->connection_op,
- simple, cancellable);
+ task, cancellable);
break;
/* If we're already connected, just report success. */
case CAMEL_SERVICE_CONNECTED:
- g_simple_async_result_complete_in_idle (simple);
+ g_task_return_boolean (task, TRUE);
break;
/* If a disconnect operation is currently in progress,
@@ -1628,7 +1636,7 @@ camel_service_connect (CamelService *service,
g_return_if_fail (
service->priv->connection_op == NULL);
- op = connection_op_new (simple, cancellable);
+ op = connection_op_new (task, cancellable);
service->priv->connection_op = op;
service->priv->status = CAMEL_SERVICE_CONNECTING;
@@ -1643,7 +1651,7 @@ camel_service_connect (CamelService *service,
g_mutex_unlock (&service->priv->connection_lock);
- g_object_unref (simple);
+ g_object_unref (task);
}
/**
@@ -1663,16 +1671,14 @@ camel_service_connect_finish (CamelService *service,
GAsyncResult *result,
GError **error)
{
- GSimpleAsyncResult *simple;
+ g_return_val_if_fail (CAMEL_IS_SERVICE (service), FALSE);
+ g_return_val_if_fail (g_task_is_valid (result, service), FALSE);
g_return_val_if_fail (
- g_simple_async_result_is_valid (
- result, G_OBJECT (service), camel_service_connect), FALSE);
+ g_async_result_is_tagged (
+ result, camel_service_connect), FALSE);
- simple = G_SIMPLE_ASYNC_RESULT (result);
-
- /* Assume success unless a GError is set. */
- return !g_simple_async_result_propagate_error (simple, error);
+ return g_task_propagate_boolean (G_TASK (result), error);
}
/**
@@ -1751,17 +1757,14 @@ camel_service_disconnect (CamelService *service,
GAsyncReadyCallback callback,
gpointer user_data)
{
+ GTask *task;
ConnectionOp *op;
- GSimpleAsyncResult *simple;
g_return_if_fail (CAMEL_IS_SERVICE (service));
- simple = g_simple_async_result_new (
- G_OBJECT (service),
- callback, user_data,
- camel_service_disconnect);
-
- g_simple_async_result_set_check_cancellable (simple, cancellable);
+ task = g_task_new (service, cancellable, callback, user_data);
+ g_task_set_source_tag (task, camel_service_disconnect);
+ g_task_set_priority (task, io_priority);
g_mutex_lock (&service->priv->connection_lock);
@@ -1785,7 +1788,7 @@ camel_service_disconnect (CamelService *service,
g_return_if_fail (
service->priv->connection_op == NULL);
- op = connection_op_new (simple, cancellable);
+ op = connection_op_new (task, cancellable);
service->priv->connection_op = op;
/* Do not change the status if CONNECTING, in case a
@@ -1808,12 +1811,12 @@ camel_service_disconnect (CamelService *service,
case CAMEL_SERVICE_DISCONNECTING:
connection_op_add_pending (
service->priv->connection_op,
- simple, cancellable);
+ task, cancellable);
break;
/* If we're already disconnected, just report success. */
case CAMEL_SERVICE_DISCONNECTED:
- g_simple_async_result_complete_in_idle (simple);
+ g_task_return_boolean (task, TRUE);
break;
default:
@@ -1822,7 +1825,7 @@ camel_service_disconnect (CamelService *service,
g_mutex_unlock (&service->priv->connection_lock);
- g_object_unref (simple);
+ g_object_unref (task);
}
/**
@@ -1842,16 +1845,14 @@ camel_service_disconnect_finish (CamelService *service,
GAsyncResult *result,
GError **error)
{
- GSimpleAsyncResult *simple;
+ g_return_val_if_fail (CAMEL_IS_SERVICE (service), FALSE);
+ g_return_val_if_fail (g_task_is_valid (result, service), FALSE);
g_return_val_if_fail (
- g_simple_async_result_is_valid (
- result, G_OBJECT (service), camel_service_disconnect), FALSE);
-
- simple = G_SIMPLE_ASYNC_RESULT (result);
+ g_async_result_is_tagged (
+ result, camel_service_disconnect), FALSE);
- /* Assume success unless a GError is set. */
- return !g_simple_async_result_propagate_error (simple, error);
+ return g_task_propagate_boolean (G_TASK (result), error);
}
/**
@@ -1911,22 +1912,27 @@ camel_service_authenticate_sync (CamelService *service,
/* Helper for camel_service_authenticate() */
static void
-service_authenticate_thread (GSimpleAsyncResult *simple,
- GObject *object,
+service_authenticate_thread (GTask *task,
+ gpointer source_object,
+ gpointer task_data,
GCancellable *cancellable)
{
+ CamelAuthenticationResult auth_result;
AsyncContext *async_context;
- GError *error = NULL;
+ GError *local_error = NULL;
- async_context = g_simple_async_result_get_op_res_gpointer (simple);
+ async_context = (AsyncContext *) task_data;
- async_context->auth_result = camel_service_authenticate_sync (
- CAMEL_SERVICE (object),
+ auth_result = camel_service_authenticate_sync (
+ CAMEL_SERVICE (source_object),
async_context->auth_mechanism,
- cancellable, &error);
+ cancellable, &local_error);
- if (error != NULL)
- g_simple_async_result_take_error (simple, error);
+ if (local_error != NULL) {
+ g_task_return_error (task, local_error);
+ } else {
+ g_task_return_int (task, auth_result);
+ }
}
/**
@@ -1959,7 +1965,7 @@ camel_service_authenticate (CamelService *service,
GAsyncReadyCallback callback,
gpointer user_data)
{
- GSimpleAsyncResult *simple;
+ GTask *task;
AsyncContext *async_context;
g_return_if_fail (CAMEL_IS_SERVICE (service));
@@ -1967,20 +1973,17 @@ camel_service_authenticate (CamelService *service,
async_context = g_slice_new0 (AsyncContext);
async_context->auth_mechanism = g_strdup (mechanism);
- simple = g_simple_async_result_new (
- G_OBJECT (service),
- callback, user_data,
- camel_service_authenticate);
-
- g_simple_async_result_set_check_cancellable (simple, cancellable);
+ task = g_task_new (service, cancellable, callback, user_data);
+ g_task_set_source_tag (task, camel_service_authenticate);
+ g_task_set_priority (task, io_priority);
- g_simple_async_result_set_op_res_gpointer (
- simple, async_context, (GDestroyNotify) async_context_free);
+ g_task_set_task_data (
+ task, async_context,
+ (GDestroyNotify) async_context_free);
- g_simple_async_result_run_in_thread (
- simple, service_authenticate_thread, io_priority, cancellable);
+ g_task_run_in_thread (task, service_authenticate_thread);
- g_object_unref (simple);
+ g_object_unref (task);
}
/**
@@ -2010,21 +2013,29 @@ camel_service_authenticate_finish (CamelService *service,
GAsyncResult *result,
GError **error)
{
- GSimpleAsyncResult *simple;
- AsyncContext *async_context;
+ CamelAuthenticationResult auth_result;
+
+ g_return_val_if_fail (
+ CAMEL_IS_SERVICE (service),
+ CAMEL_AUTHENTICATION_REJECTED);
+ g_return_val_if_fail (
+ g_task_is_valid (result, service),
+ CAMEL_AUTHENTICATION_REJECTED);
g_return_val_if_fail (
- g_simple_async_result_is_valid (
- result, G_OBJECT (service), camel_service_authenticate),
+ g_async_result_is_tagged (
+ result, camel_service_authenticate),
CAMEL_AUTHENTICATION_REJECTED);
- simple = G_SIMPLE_ASYNC_RESULT (result);
- async_context = g_simple_async_result_get_op_res_gpointer (simple);
+ /* XXX A little hackish, but best way to return enum values
+ * from GTask in GLib 2.36. Recommended by Dan Winship. */
- if (g_simple_async_result_propagate_error (simple, error))
+ auth_result = g_task_propagate_int (G_TASK (result), error);
+
+ if (auth_result == (CamelAuthenticationResult) -1)
return CAMEL_AUTHENTICATION_ERROR;
- return async_context->auth_result;
+ return auth_result;
}
/**
@@ -2055,20 +2066,26 @@ camel_service_query_auth_types_sync (CamelService *service,
/* Helper for camel_service_query_auth_types() */
static void
-service_query_auth_types_thread (GSimpleAsyncResult *simple,
- GObject *object,
+service_query_auth_types_thread (GTask *task,
+ gpointer source_object,
+ gpointer task_data,
GCancellable *cancellable)
{
- AsyncContext *async_context;
- GError *error = NULL;
-
- async_context = g_simple_async_result_get_op_res_gpointer (simple);
+ GList *auth_types;
+ GError *local_error = NULL;
- async_context->auth_types = camel_service_query_auth_types_sync (
- CAMEL_SERVICE (object), cancellable, &error);
+ auth_types = camel_service_query_auth_types_sync (
+ CAMEL_SERVICE (source_object),
+ cancellable, &local_error);
- if (error != NULL)
- g_simple_async_result_take_error (simple, error);
+ if (local_error != NULL) {
+ g_warn_if_fail (auth_types == NULL);
+ g_task_return_error (task, local_error);
+ } else {
+ g_task_return_pointer (
+ task, auth_types,
+ (GDestroyNotify) g_list_free);
+ }
}
/**
@@ -2095,28 +2112,17 @@ camel_service_query_auth_types (CamelService *service,
GAsyncReadyCallback callback,
gpointer user_data)
{
- GSimpleAsyncResult *simple;
- AsyncContext *async_context;
+ GTask *task;
g_return_if_fail (CAMEL_IS_SERVICE (service));
- async_context = g_slice_new0 (AsyncContext);
+ task = g_task_new (service, cancellable, callback, user_data);
+ g_task_set_source_tag (task, camel_service_query_auth_types);
+ g_task_set_priority (task, io_priority);
- simple = g_simple_async_result_new (
- G_OBJECT (service),
- callback, user_data,
- camel_service_query_auth_types);
+ g_task_run_in_thread (task, service_query_auth_types_thread);
- g_simple_async_result_set_check_cancellable (simple, cancellable);
-
- g_simple_async_result_set_op_res_gpointer (
- simple, async_context, (GDestroyNotify) async_context_free);
-
- g_simple_async_result_run_in_thread (
- simple, service_query_auth_types_thread,
- io_priority, cancellable);
-
- g_object_unref (simple);
+ g_object_unref (task);
}
/**
@@ -2137,20 +2143,13 @@ camel_service_query_auth_types_finish (CamelService *service,
GAsyncResult *result,
GError **error)
{
- GSimpleAsyncResult *simple;
- AsyncContext *async_context;
+ g_return_val_if_fail (CAMEL_IS_SERVICE (service), NULL);
+ g_return_val_if_fail (g_task_is_valid (result, service), NULL);
g_return_val_if_fail (
- g_simple_async_result_is_valid (
- result, G_OBJECT (service),
- camel_service_query_auth_types), NULL);
-
- simple = G_SIMPLE_ASYNC_RESULT (result);
- async_context = g_simple_async_result_get_op_res_gpointer (simple);
-
- if (g_simple_async_result_propagate_error (simple, error))
- return NULL;
+ g_async_result_is_tagged (
+ result, camel_service_query_auth_types), NULL);
- return g_list_copy (async_context->auth_types);
+ return g_task_propagate_pointer (G_TASK (result), error);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]