[evolution-data-server] Add CamelAsyncClosure.
- From: Matthew Barnes <mbarnes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] Add CamelAsyncClosure.
- Date: Sun, 1 Dec 2013 15:59:02 +0000 (UTC)
commit 1bcf522ad3a02efdf8fbf398c4f658b970bb285d
Author: Matthew Barnes <mbarnes redhat com>
Date: Sun Dec 1 09:01:43 2013 -0500
Add CamelAsyncClosure.
Identical to EAsyncClosure in libedataserver, for use in Camel.
camel/Makefile.am | 2 +
camel/camel-async-closure.c | 164 +++++++++++++++++++++++++++++++
camel/camel-async-closure.h | 39 +++++++
camel/camel.h | 1 +
docs/reference/camel/camel-docs.sgml | 1 +
docs/reference/camel/camel-sections.txt | 10 ++
6 files changed, 217 insertions(+), 0 deletions(-)
---
diff --git a/camel/Makefile.am b/camel/Makefile.am
index d6d92c4..edd4454 100644
--- a/camel/Makefile.am
+++ b/camel/Makefile.am
@@ -63,6 +63,7 @@ libcamel_1_2_la_CPPFLAGS = \
libcamel_1_2_la_SOURCES = \
$(ENUM_GENERATED) \
camel-address.c \
+ camel-async-closure.c \
camel-block-file.c \
camel-certdb.c \
camel-charset-map.c \
@@ -175,6 +176,7 @@ libcamel_1_2_la_SOURCES = \
libcamelinclude_HEADERS = \
camel-address.h \
+ camel-async-closure.h \
camel-block-file.h \
camel-certdb.h \
camel-charset-map.h \
diff --git a/camel/camel-async-closure.c b/camel/camel-async-closure.c
new file mode 100644
index 0000000..c7b0850
--- /dev/null
+++ b/camel/camel-async-closure.c
@@ -0,0 +1,164 @@
+/*
+ * camel-async-closure.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+/**
+ * SECTION: camel-async-closure
+ * @short_description: Run asynchronous functions synchronously
+ * @include: camel/camel.h
+ *
+ * #CamelAsyncClosure provides a simple way to run an asynchronous function
+ * synchronously without blocking the current thread.
+ *
+ * 1) Create a #CamelAsyncClosure with camel_async_closure_new().
+ *
+ * 2) Call the asynchronous function passing camel_async_closure_callback()
+ * as the #GAsyncReadyCallback argument and the #CamelAsyncClosure as the
+ * data argument.
+ *
+ * 3) Call camel_async_closure_wait() and collect the #GAsyncResult.
+ *
+ * 4) Call the corresponding asynchronous "finish" function, passing the
+ * #GAsyncResult returned by camel_async_closure_wait().
+ *
+ * 5) If needed, repeat steps 2-4 for additional asynchronous functions
+ * using the same #CamelAsyncClosure.
+ *
+ * 6) Finally, free the #CamelAsyncClosure with camel_async_closure_free().
+ **/
+
+#include "camel-async-closure.h"
+
+/**
+ * CamelAsyncClosure:
+ *
+ * Contains only private data that should be read and manipulated using the
+ * functions below.
+ *
+ * Since: 3.12
+ **/
+struct _CamelAsyncClosure {
+ GMainLoop *loop;
+ GMainContext *context;
+ GAsyncResult *result;
+};
+
+/**
+ * camel_async_closure_new:
+ *
+ * Creates a new #CamelAsyncClosure for use with asynchronous functions.
+ *
+ * Returns: a new #CamelAsyncClosure
+ *
+ * Since: 3.12
+ **/
+CamelAsyncClosure *
+camel_async_closure_new (void)
+{
+ CamelAsyncClosure *closure;
+
+ closure = g_slice_new0 (CamelAsyncClosure);
+ closure->context = g_main_context_new ();
+ closure->loop = g_main_loop_new (closure->context, FALSE);
+
+ g_main_context_push_thread_default (closure->context);
+
+ return closure;
+}
+
+/**
+ * camel_async_closure_wait:
+ * @closure: a #CamelAsyncClosure
+ *
+ * Call this function immediately after starting an asynchronous operation.
+ * The function waits for the asynchronous operation to complete and returns
+ * its #GAsyncResult to be passed to the operation's "finish" function.
+ *
+ * This function can be called repeatedly on the same #CamelAsyncClosure to
+ * easily string together multiple asynchronous operations.
+ *
+ * Returns: (transfer none): a #GAsyncResult which is owned by the closure
+ *
+ * Since: 3.12
+ **/
+GAsyncResult *
+camel_async_closure_wait (CamelAsyncClosure *closure)
+{
+ g_return_val_if_fail (closure != NULL, NULL);
+
+ g_main_loop_run (closure->loop);
+
+ return closure->result;
+}
+
+/**
+ * camel_async_closure_free:
+ * @closure: a #CamelAsyncClosure
+ *
+ * Frees the @closure and the resources it holds.
+ *
+ * Since: 3.12
+ **/
+void
+camel_async_closure_free (CamelAsyncClosure *closure)
+{
+ g_return_if_fail (closure != NULL);
+
+ g_main_context_pop_thread_default (closure->context);
+
+ g_main_loop_unref (closure->loop);
+ g_main_context_unref (closure->context);
+
+ if (closure->result != NULL)
+ g_object_unref (closure->result);
+
+ g_slice_free (CamelAsyncClosure, closure);
+}
+
+/**
+ * camel_async_closure_callback:
+ * @source_object: a #GObject or %NULL
+ * @result: a #GAsyncResult
+ * @closure: a #CamelAsyncClosure
+ *
+ * Pass this function as the #GAsyncReadyCallback argument of an asynchronous
+ * function, and the #CamelAsyncClosure as the data argument.
+ *
+ * This causes camel_async_closure_wait() to terminate and return @result.
+ *
+ * Since: 3.12
+ **/
+void
+camel_async_closure_callback (GObject *source_object,
+ GAsyncResult *result,
+ gpointer closure)
+{
+ CamelAsyncClosure *real_closure;
+
+ g_return_if_fail (G_IS_ASYNC_RESULT (result));
+ g_return_if_fail (closure != NULL);
+
+ real_closure = closure;
+
+ /* Replace any previous result. */
+ if (real_closure->result != NULL)
+ g_object_unref (real_closure->result);
+ real_closure->result = g_object_ref (result);
+
+ g_main_loop_quit (real_closure->loop);
+}
+
diff --git a/camel/camel-async-closure.h b/camel/camel-async-closure.h
new file mode 100644
index 0000000..36ca394
--- /dev/null
+++ b/camel/camel-async-closure.h
@@ -0,0 +1,39 @@
+/*
+ * camel-async-closure.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#if !defined (__CAMEL_H_INSIDE__) && !defined (CAMEL_COMPILATION)
+#error "Only <camel/camel.h> can be included directly."
+#endif
+
+#ifndef CAMEL_ASYNC_CLOSURE_H
+#define CAMEL_ASYNC_CLOSURE_H
+
+#include <gio/gio.h>
+
+typedef struct _CamelAsyncClosure CamelAsyncClosure;
+
+CamelAsyncClosure *
+ camel_async_closure_new (void);
+GAsyncResult * camel_async_closure_wait (CamelAsyncClosure *closure);
+void camel_async_closure_free (CamelAsyncClosure *closure);
+void camel_async_closure_callback (GObject *source_object,
+ GAsyncResult *result,
+ gpointer closure);
+
+#endif /* CAMEL_ASYNC_CLOSURE_H */
+
diff --git a/camel/camel.h b/camel/camel.h
index 3a06090..6a8f485 100644
--- a/camel/camel.h
+++ b/camel/camel.h
@@ -27,6 +27,7 @@
#define __CAMEL_H_INSIDE__
#include <camel/camel-address.h>
+#include <camel/camel-async-closure.h>
#include <camel/camel-block-file.h>
#include <camel/camel-certdb.h>
#include <camel/camel-charset-map.h>
diff --git a/docs/reference/camel/camel-docs.sgml b/docs/reference/camel/camel-docs.sgml
index b0ca1ec..9b4f01f 100644
--- a/docs/reference/camel/camel-docs.sgml
+++ b/docs/reference/camel/camel-docs.sgml
@@ -171,6 +171,7 @@
<chapter id="Utilities">
<title>Utilities</title>
+ <xi:include href="xml/camel-async-closure.xml"/>
<xi:include href="xml/camel-charset-map.xml"/>
<xi:include href="xml/camel-file-utils.xml"/>
<xi:include href="xml/camel-iconv.xml"/>
diff --git a/docs/reference/camel/camel-sections.txt b/docs/reference/camel/camel-sections.txt
index b8fa92b..02aaa39 100644
--- a/docs/reference/camel/camel-sections.txt
+++ b/docs/reference/camel/camel-sections.txt
@@ -26,6 +26,16 @@ CamelAddressPrivate
</SECTION>
<SECTION>
+<FILE>camel-async-closure</FILE>
+<TITLE>CamelAsyncClosure</TITLE>
+CamelAsyncClosure
+camel_async_closure_new
+camel_async_closure_wait
+camel_async_closure_free
+camel_async_closure_callback
+</SECTION>
+
+<SECTION>
<FILE>camel-block-file</FILE>
<TITLE>CamelBlockFile</TITLE>
<TITLE>CamelKeyFile</TITLE>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]