diff options
author | Colin Walters <walters@verbum.org> | 2011-11-27 17:21:04 -0500 |
---|---|---|
committer | Colin Walters <walters@verbum.org> | 2011-11-27 17:21:04 -0500 |
commit | b0b0ffcd61902125c29ddc6044d7806c97e35a85 (patch) | |
tree | 62fd864a7427b1ab23f08daff05d5534a4567b25 | |
parent | 8af4a62665ee1bb1dab9eb02e7d5a03c86807a02 (diff) | |
download | ostree-b0b0ffcd61902125c29ddc6044d7806c97e35a85.tar.gz |
core: Add asynchronous checksum API, use it in checksum builtin
-rw-r--r-- | src/libostree/ostree-core.c | 82 | ||||
-rw-r--r-- | src/libostree/ostree-core.h | 12 | ||||
-rw-r--r-- | 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 943c17e8..0f3a7109 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 72d921a4..038fb511 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 d83e3271..d6536e3b 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); |