[evolution-data-server] Add CamelAsyncClosure.



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]