repo/private: move OstreeRepoAutoTransaction to a boxed type
authorLuca BRUNO <luca.bruno@coreos.com>
Mon, 11 Oct 2021 06:52:25 +0000 (06:52 +0000)
committerLuca BRUNO <luca.bruno@coreos.com>
Mon, 11 Oct 2021 06:52:25 +0000 (06:52 +0000)
This defines `OstreeRepoAutoTransaction` as a boxed type, in order
to support auto-generating bindings for it.
That first requires adding internal reference-counting to it, to
allow freely copying/freeing references to a single transaction guard.

src/libostree/ostree-repo-private.h
src/libostree/ostree-repo.c

index a2666dec6a8092bc45711a9af542b26e13f6d28a..daec289c461909b77983651df3f1a860ec5adeab 100644 (file)
@@ -525,6 +525,7 @@ _ostree_repo_verify_bindings (const char  *collection_id,
  */
 typedef struct
 {
+  gint atomic_refcount;
   OstreeRepo *repo;
 } OstreeRepoAutoTransaction;
 
@@ -544,9 +545,14 @@ _ostree_repo_auto_transaction_commit (OstreeRepoAutoTransaction  *txn,
                                       GCancellable               *cancellable,
                                       GError                    **error);
 
+OstreeRepoAutoTransaction *
+_ostree_repo_auto_transaction_ref (OstreeRepoAutoTransaction *txn);
+
 void
-_ostree_repo_auto_transaction_cleanup (void *p);
+_ostree_repo_auto_transaction_unref (OstreeRepoAutoTransaction *txn);
+
+GType _ostree_repo_auto_transaction_get_type (void);
 
-G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeRepoAutoTransaction, _ostree_repo_auto_transaction_cleanup);
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeRepoAutoTransaction, _ostree_repo_auto_transaction_unref);
 
 G_END_DECLS
index 772eae26e55fe7cee0405d33303744d9ce142507..74cea37f235ff0712c1faf7e4335bcff5020040e 100644 (file)
@@ -711,10 +711,9 @@ ostree_repo_auto_lock_cleanup (OstreeRepoAutoLock *auto_lock)
     }
 }
 
-
 /**
  * _ostree_repo_auto_transaction_start:
- * @repo: an #OsreeRepo object
+ * @repo: (not nullable): an #OsreeRepo object
  * @cancellable: Cancellable
  * @error: a #GError
  *
@@ -734,6 +733,7 @@ _ostree_repo_auto_transaction_start (OstreeRepo     *repo,
     return NULL;
 
   OstreeRepoAutoTransaction *txn = g_malloc(sizeof(OstreeRepoAutoTransaction));
+  txn->atomic_refcount = 1;
   txn->repo = g_object_ref (repo);
 
   return g_steal_pointer (&txn);
@@ -741,7 +741,7 @@ _ostree_repo_auto_transaction_start (OstreeRepo     *repo,
 
 /**
  * _ostree_repo_auto_transaction_abort:
- * @txn: an #OsreeRepoAutoTransaction guard
+ * @txn: (not nullable): an #OsreeRepoAutoTransaction guard
  * @cancellable: Cancellable
  * @error: a #GError
  *
@@ -770,7 +770,8 @@ _ostree_repo_auto_transaction_abort (OstreeRepoAutoTransaction  *txn,
 
 /**
  * _ostree_repo_auto_transaction_commit:
- * @txn: an #OsreeRepoAutoTransaction guard
+ * @txn: (not nullable): an #OsreeRepoAutoTransaction guard
+ * @out_stats: (out) (allow-none): transaction result statistics
  * @cancellable: Cancellable
  * @error: a #GError
  *
@@ -799,30 +800,58 @@ _ostree_repo_auto_transaction_commit (OstreeRepoAutoTransaction  *txn,
 }
 
 /**
- * _ostree_repo_auto_transaction_cleanup:
- * @p: pointer to an #OsreeRepoAutoTransaction guard
+ * _ostree_repo_auto_transaction_ref:
+ * @txn: (not nullable): an #OsreeRepoAutoTransaction guard
+ *
+ * Return a new reference to the transaction guard.
+ *
+ * Returns: (transfer full) (not nullable): new transaction guard reference.
+ */
+OstreeRepoAutoTransaction *
+_ostree_repo_auto_transaction_ref (OstreeRepoAutoTransaction *txn)
+{
+  g_assert (txn != NULL);
+
+  gint refcount = g_atomic_int_add (&txn->atomic_refcount, 1);
+  g_assert (refcount > 1);
+
+  return txn;
+}
+
+/**
+ * _ostree_repo_auto_transaction_unref:
+ * @txn: (transfer full): an #OsreeRepoAutoTransaction guard
  *
- * Destroy a transaction guard. If the transaction has not yet been completed,
- * it gets aborted.
+ * Unreference a transaction guard. When the last reference is gone,
+ * if the transaction has not yet been completed, it gets aborted.
  */
 void
-_ostree_repo_auto_transaction_cleanup (void *p)
+_ostree_repo_auto_transaction_unref (OstreeRepoAutoTransaction *txn)
 {
-  if (p == NULL)
+  if (txn == NULL)
+    return;
+
+  if (!g_atomic_int_dec_and_test (&txn->atomic_refcount))
     return;
 
-  OstreeRepoAutoTransaction *txn = p;
   // Auto-abort only if transaction has not already been aborted/committed.
   if (txn->repo != NULL)
     {
       g_autoptr(GError) error = NULL;
-      if (!_ostree_repo_auto_transaction_abort (txn, NULL, &error)) {
+      if (!ostree_repo_abort_transaction (txn->repo, NULL, &error))
         g_warning("Failed to auto-cleanup OSTree transaction: %s", error->message);
-        g_clear_object (&txn->repo);
-      }
+
+      g_clear_object (&txn->repo);
     }
+
+  g_free (txn);
+  return;
 }
 
+G_DEFINE_BOXED_TYPE(OstreeRepoAutoTransaction, _ostree_repo_auto_transaction,
+                    _ostree_repo_auto_transaction_ref,
+                    _ostree_repo_auto_transaction_unref);
+
 static GFile *
 get_remotes_d_dir (OstreeRepo          *self,
                    GFile               *sysroot);