From 7d863ed9e4c15725c8439b389b5657872db1bd85 Mon Sep 17 00:00:00 2001 From: Dan Nicholson Date: Fri, 13 Oct 2017 19:31:35 +0000 Subject: [PATCH] lib/repo: Add locking auto cleanup handler Define an auto cleanup handler for use with repo locking. This is based on the existing auto transaction cleanup. A wrapper for ostree_repo_lock_push() is added with it. The intended usage is like so: g_autoptr(OstreeRepoAutoLock) lock = NULL; lock = ostree_repo_auto_lock_push (repo, lock_type, cancellable, error); if (!lock) return FALSE; The functions and type are marked to be skipped by introspection since I can't see them being usable from bindings. Closes: #1343 Approved by: cgwalters --- apidoc/ostree-experimental-sections.txt | 3 ++ src/libostree/libostree-experimental.sym | 2 + src/libostree/ostree-autocleanups.h | 1 + src/libostree/ostree-repo-private.h | 9 ++++ src/libostree/ostree-repo.c | 60 ++++++++++++++++++++++++ src/libostree/ostree-repo.h | 18 +++++++ 6 files changed, 93 insertions(+) diff --git a/apidoc/ostree-experimental-sections.txt b/apidoc/ostree-experimental-sections.txt index 61f43f28..0d168406 100644 --- a/apidoc/ostree-experimental-sections.txt +++ b/apidoc/ostree-experimental-sections.txt @@ -93,6 +93,9 @@ ostree_repo_finder_override_get_type OstreeRepoLockType ostree_repo_lock_push ostree_repo_lock_pop +OstreeRepoAutoLock +ostree_repo_auto_lock_push +ostree_repo_auto_lock_cleanup ostree_repo_get_collection_id ostree_repo_set_collection_id ostree_validate_collection_id diff --git a/src/libostree/libostree-experimental.sym b/src/libostree/libostree-experimental.sym index 15730546..3f3454f3 100644 --- a/src/libostree/libostree-experimental.sym +++ b/src/libostree/libostree-experimental.sym @@ -94,6 +94,8 @@ LIBOSTREE_2017.14_EXPERIMENTAL { global: ostree_remote_get_type; ostree_remote_get_url; + ostree_repo_auto_lock_cleanup; + ostree_repo_auto_lock_push; ostree_repo_lock_pop; ostree_repo_lock_push; } LIBOSTREE_2017.13_EXPERIMENTAL; diff --git a/src/libostree/ostree-autocleanups.h b/src/libostree/ostree-autocleanups.h index c8e8a857..b3974317 100644 --- a/src/libostree/ostree-autocleanups.h +++ b/src/libostree/ostree-autocleanups.h @@ -59,6 +59,7 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeSysrootUpgrader, g_object_unref) G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC (OstreeRepoCommitTraverseIter, ostree_repo_commit_traverse_iter_clear) #ifdef OSTREE_ENABLE_EXPERIMENTAL_API +G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeRepoAutoLock, ostree_repo_auto_lock_cleanup) G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeCollectionRef, ostree_collection_ref_free) G_DEFINE_AUTO_CLEANUP_FREE_FUNC (OstreeCollectionRefv, ostree_collection_ref_freev, NULL) G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeRemote, ostree_remote_unref) diff --git a/src/libostree/ostree-repo-private.h b/src/libostree/ostree-repo-private.h index 452b2b35..ae51cea3 100644 --- a/src/libostree/ostree-repo-private.h +++ b/src/libostree/ostree-repo-private.h @@ -456,6 +456,15 @@ gboolean ostree_repo_lock_pop (OstreeRepo *self, GCancellable *cancellable, GError **error); +typedef OstreeRepo OstreeRepoAutoLock; + +OstreeRepoAutoLock * ostree_repo_auto_lock_push (OstreeRepo *self, + OstreeRepoLockType lock_type, + GCancellable *cancellable, + GError **error); +void ostree_repo_auto_lock_cleanup (OstreeRepoAutoLock *lock); +G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeRepoAutoLock, ostree_repo_auto_lock_cleanup) + const gchar * ostree_repo_get_collection_id (OstreeRepo *self); gboolean ostree_repo_set_collection_id (OstreeRepo *self, const gchar *collection_id, diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c index 9c2d5fb5..039f437b 100644 --- a/src/libostree/ostree-repo.c +++ b/src/libostree/ostree-repo.c @@ -612,6 +612,66 @@ ostree_repo_lock_pop (OstreeRepo *self, } } +/** + * ostree_repo_auto_lock_push: (skip) + * @self: a #OstreeRepo + * @lock_type: the type of lock to acquire + * @cancellable: a #GCancellable + * @error: a #GError + * + * Like ostree_repo_lock_push(), but for usage with #OstreeRepoAutoLock. + * The intended usage is to declare the #OstreeRepoAutoLock with + * g_autoptr() so that ostree_repo_auto_lock_cleanup() is called when it + * goes out of scope. This will automatically pop the lock status off + * the stack if it was acquired successfully. + * + * |[ + * g_autoptr(OstreeRepoAutoLock) lock = NULL; + * lock = ostree_repo_auto_lock_push (repo, lock_type, cancellable, error); + * if (!lock) + * return FALSE; + * ]| + * + * Returns: @self on success, otherwise %NULL with @error set + * Since: 2017.14 + */ +OstreeRepoAutoLock * +ostree_repo_auto_lock_push (OstreeRepo *self, + OstreeRepoLockType lock_type, + GCancellable *cancellable, + GError **error) +{ + if (!ostree_repo_lock_push (self, lock_type, cancellable, error)) + return NULL; + return (OstreeRepoAutoLock *)self; +} + +/** + * ostree_repo_auto_lock_cleanup: (skip) + * @lock: a #OstreeRepoAutoLock + * + * A cleanup handler for use with ostree_repo_auto_lock_push(). If @lock is + * not %NULL, ostree_repo_lock_pop() will be called on it. If + * ostree_repo_lock_pop() fails, a critical warning will be emitted. + * + * Since: 2017.14 + */ +void +ostree_repo_auto_lock_cleanup (OstreeRepoAutoLock *lock) +{ + OstreeRepo *repo = lock; + if (repo) + { + g_autoptr(GError) error = NULL; + int errsv = errno; + + if (!ostree_repo_lock_pop (repo, NULL, &error)) + g_critical ("Cleanup repo lock failed: %s", error->message); + + errno = errsv; + } +} + static GFile * get_remotes_d_dir (OstreeRepo *self, GFile *sysroot); diff --git a/src/libostree/ostree-repo.h b/src/libostree/ostree-repo.h index 13074582..7ce47a56 100644 --- a/src/libostree/ostree-repo.h +++ b/src/libostree/ostree-repo.h @@ -131,6 +131,24 @@ gboolean ostree_repo_lock_pop (OstreeRepo *self, GCancellable *cancellable, GError **error); +/** + * OstreeRepoAutoLock: (skip) + * + * This is simply an alias to #OstreeRepo used for automatic lock cleanup. + * See ostree_repo_auto_lock_push() for its intended usage. + * + * Since: 2017.14 + */ +typedef OstreeRepo OstreeRepoAutoLock; + +_OSTREE_PUBLIC +OstreeRepoAutoLock * ostree_repo_auto_lock_push (OstreeRepo *self, + OstreeRepoLockType lock_type, + GCancellable *cancellable, + GError **error); +_OSTREE_PUBLIC +void ostree_repo_auto_lock_cleanup (OstreeRepoAutoLock *lock); + _OSTREE_PUBLIC const gchar * ostree_repo_get_collection_id (OstreeRepo *self); _OSTREE_PUBLIC