[ostree] core: Add asynchronous checksum API, use it in checksum builtin



commit b0b0ffcd61902125c29ddc6044d7806c97e35a85
Author: Colin Walters <walters verbum org>
Date:   Sun Nov 27 17:21:04 2011 -0500

    core: Add asynchronous checksum API, use it in checksum builtin

 src/libostree/ostree-core.c      |   82 ++++++++++++++++++++++++++++++++++++-
 src/libostree/ostree-core.h      |   12 ++++++
 src/ostree/ot-builtin-checksum.c |   38 ++++++++++++++---
 3 files changed, 122 insertions(+), 10 deletions(-)
---
diff --git a/src/libostree/ostree-core.c b/src/libostree/ostree-core.c
index 943c17e..0f3a710 100644
--- a/src/libostree/ostree-core.c
+++ b/src/libostree/ostree-core.c
@@ -320,6 +320,9 @@ ostree_checksum_file (GFile            *f,
   GFileInfo *file_info = NULL;
   GChecksum *ret_checksum = NULL;
 
+  if (g_cancellable_set_error_if_cancelled (cancellable, error))
+    return NULL;
+
   file_info = g_file_query_info (f, OSTREE_GIO_FAST_QUERYINFO,
                                  G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                                  cancellable, error);
@@ -345,6 +348,82 @@ ostree_checksum_file (GFile            *f,
   return ret;
 }
 
+typedef struct {
+  GFile  *f;
+  OstreeObjectType objtype;
+  GChecksum *checksum;
+} ChecksumFileAsyncData;
+
+static void
+checksum_file_async_thread (GSimpleAsyncResult  *res,
+                            GObject             *object,
+                            GCancellable        *cancellable)
+{
+  GError *error = NULL;
+  ChecksumFileAsyncData *data;
+  GChecksum *checksum = NULL;
+
+  data = g_simple_async_result_get_op_res_gpointer (res);
+  if (!ostree_checksum_file (data->f, data->objtype, &checksum, cancellable, &error))
+    g_simple_async_result_take_error (res, error);
+  else
+    data->checksum = checksum;
+}
+
+static void
+checksum_file_async_data_free (gpointer datap)
+{
+  ChecksumFileAsyncData *data = datap;
+
+  g_object_unref (data->f);
+  if (data->checksum)
+    g_checksum_free (data->checksum);
+  g_free (data);
+}
+  
+void
+ostree_checksum_file_async (GFile                 *f,
+                            OstreeObjectType       objtype,
+                            int                    io_priority,
+                            GCancellable          *cancellable,
+                            GAsyncReadyCallback    callback,
+                            gpointer               user_data)
+{
+  GSimpleAsyncResult  *res;
+  ChecksumFileAsyncData *data;
+
+  data = g_new0 (ChecksumFileAsyncData, 1);
+  data->f = g_object_ref (f);
+  data->objtype = objtype;
+
+  res = g_simple_async_result_new (G_OBJECT (f), callback, user_data, ostree_checksum_file_async);
+  g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)checksum_file_async_data_free);
+  
+  g_simple_async_result_run_in_thread (res, checksum_file_async_thread, io_priority, cancellable);
+  g_object_unref (res);
+}
+
+gboolean
+ostree_checksum_file_async_finish (GFile          *f,
+                                   GAsyncResult   *result,
+                                   GChecksum     **out_checksum,
+                                   GError        **error)
+{
+  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
+  ChecksumFileAsyncData *data;
+
+  g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == ostree_checksum_file_async);
+
+  if (g_simple_async_result_propagate_error (simple, error))
+    return FALSE;
+
+  data = g_simple_async_result_get_op_res_gpointer (simple);
+  /* Transfer ownership */
+  *out_checksum = data->checksum;
+  data->checksum = NULL;
+  return TRUE;
+}
+
 gboolean
 ostree_get_directory_metadata (GFile        *dir,
                                GFileInfo    *dir_info,
@@ -912,6 +991,3 @@ ostree_unpack_object (GFile            *file,
   else
     return unpack_file (file, dest, out_checksum, error);
 }
-  
-
-
diff --git a/src/libostree/ostree-core.h b/src/libostree/ostree-core.h
index 72d921a..038fb51 100644
--- a/src/libostree/ostree-core.h
+++ b/src/libostree/ostree-core.h
@@ -116,6 +116,18 @@ gboolean ostree_checksum_file (GFile             *f,
                                GCancellable      *cancellable,
                                GError           **error);
 
+void ostree_checksum_file_async (GFile                 *f,
+                                 OstreeObjectType       objtype,
+                                 int                    io_priority,
+                                 GCancellable          *cancellable,
+                                 GAsyncReadyCallback    callback,
+                                 gpointer               user_data);
+
+gboolean ostree_checksum_file_async_finish (GFile          *f,
+                                            GAsyncResult   *result,
+                                            GChecksum     **out_checksum,
+                                            GError        **error);
+
 gboolean ostree_get_directory_metadata (GFile *dir,
                                         GFileInfo *dir_info,
                                         GVariant  **out_metadata,
diff --git a/src/ostree/ot-builtin-checksum.c b/src/ostree/ot-builtin-checksum.c
index d83e327..d6536e3 100644
--- a/src/ostree/ot-builtin-checksum.c
+++ b/src/ostree/ot-builtin-checksum.c
@@ -31,13 +31,36 @@ static GOptionEntry options[] = {
   { NULL }
 };
 
+typedef struct {
+  GError **error;
+  GMainLoop *loop;
+} AsyncChecksumData;
+
+static void
+on_checksum_received (GObject    *obj,
+                      GAsyncResult  *result,
+                      gpointer       user_data)
+{
+  GChecksum *checksum = NULL;
+  AsyncChecksumData *data = user_data;
+
+  if (!ostree_checksum_file_async_finish ((GFile*)obj, result, &checksum, data->error))
+    return;
+
+  g_print ("%s\n", g_checksum_get_string (checksum));
+ 
+  g_checksum_free (checksum);
+  
+  g_main_loop_quit (data->loop);
+}
+
 gboolean
 ostree_builtin_checksum (int argc, char **argv, const char *repo_path, GError **error)
 {
   GOptionContext *context;
   gboolean ret = FALSE;
-  GChecksum *checksum = NULL;
   GFile *f = NULL;
+  AsyncChecksumData data;
 
   context = g_option_context_new ("FILENAME - Checksum a file or directory");
   g_option_context_add_main_entries (context, options, NULL);
@@ -54,15 +77,16 @@ ostree_builtin_checksum (int argc, char **argv, const char *repo_path, GError **
       goto out;
     }
 
-  if (!ostree_checksum_file (f, OSTREE_OBJECT_TYPE_FILE, &checksum, NULL, error))
-    goto out;
+  data.loop = g_main_loop_new (NULL, FALSE);
+  data.error = error;
+  ostree_checksum_file_async (f, OSTREE_OBJECT_TYPE_FILE, G_PRIORITY_DEFAULT, NULL, on_checksum_received, &data);
+  
+  g_main_loop_run (data.loop);
 
-  g_print ("%s\n", g_checksum_get_string (checksum));
- 
   ret = TRUE;
  out:
-  if (checksum)
-    g_checksum_free (checksum);
+  if (data.loop)
+    g_main_loop_unref (data.loop);
   g_clear_object (&f);
   if (context)
     g_option_context_free (context);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]