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
This commit is contained in:
Dan Nicholson 2017-10-13 19:31:35 +00:00 committed by Atomic Bot
parent 4e78ddd2da
commit 7d863ed9e4
6 changed files with 93 additions and 0 deletions

View File

@ -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

View File

@ -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;

View File

@ -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)

View File

@ -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,

View File

@ -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.
*
* |[<!-- language="C" -->
* 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);

View File

@ -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