[PATCH v6 28/42] refs.c: add transaction.status and track OPEN/CLOSED/ERROR
From: Ronnie Sahlberg <hidden>
Date: 2016-06-15 23:00:57
Subsystem:
the rest · Maintainer:
Linus Torvalds
Track the status of a transaction in a new status field. Check the field for sanity, i.e. that status must be OPEN when _commit/_create/_delete or _update is called or else die(BUG:...) Signed-off-by: Ronnie Sahlberg <redacted> --- refs.c | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-)
diff --git a/refs.c b/refs.c
index a82d6ba..206e1a2 100644
--- a/refs.c
+++ b/refs.c@@ -3288,6 +3288,12 @@ struct ref_update { const char refname[FLEX_ARRAY]; }; +enum ref_transaction_status { + REF_TRANSACTION_OPEN = 0, + REF_TRANSACTION_CLOSED = 1, + REF_TRANSACTION_ERROR = 2, +}; + /* * Data structure for holding a reference transaction, which can * consist of checks and updates to multiple references, carried out
@@ -3297,6 +3303,7 @@ struct ref_transaction { struct ref_update **updates; size_t alloc; size_t nr; + enum ref_transaction_status status; }; struct ref_transaction *ref_transaction_begin(void)
@@ -3320,6 +3327,11 @@ void ref_transaction_free(struct ref_transaction *transaction) void ref_transaction_rollback(struct ref_transaction *transaction) { + if (!transaction) + return; + + transaction->status = REF_TRANSACTION_ERROR; + ref_transaction_free(transaction); }
@@ -3344,7 +3356,10 @@ int ref_transaction_update(struct ref_transaction *transaction, struct ref_update *update; if (have_old && !old_sha1) - die("have_old is true but old_sha1 is NULL"); + die("BUG: have_old is true but old_sha1 is NULL"); + + if (transaction->status != REF_TRANSACTION_OPEN) + die("BUG: update on transaction that is not open"); update = add_update(transaction, refname); hashcpy(update->new_sha1, new_sha1);
@@ -3363,7 +3378,10 @@ int ref_transaction_create(struct ref_transaction *transaction, struct ref_update *update; if (!new_sha1 || is_null_sha1(new_sha1)) - die("create ref with null new_sha1"); + die("BUG: create ref with null new_sha1"); + + if (transaction->status != REF_TRANSACTION_OPEN) + die("BUG: create on transaction that is not open"); update = add_update(transaction, refname);
@@ -3382,7 +3400,10 @@ int ref_transaction_delete(struct ref_transaction *transaction, struct ref_update *update; if (have_old && !old_sha1) - die("have_old is true but old_sha1 is NULL"); + die("BUG: have_old is true but old_sha1 is NULL"); + + if (transaction->status != REF_TRANSACTION_OPEN) + die("BUG: delete on transaction that is not open"); update = add_update(transaction, refname); update->flags = flags;
@@ -3454,8 +3475,13 @@ int ref_transaction_commit(struct ref_transaction *transaction, int n = transaction->nr; struct ref_update **updates = transaction->updates; - if (!n) + if (transaction->status != REF_TRANSACTION_OPEN) + die("BUG: commit on transaction that is not open"); + + if (!n) { + transaction->status = REF_TRANSACTION_CLOSED; return 0; + } /* Allocate work space */ delnames = xmalloc(sizeof(*delnames) * n);
@@ -3517,6 +3543,9 @@ int ref_transaction_commit(struct ref_transaction *transaction, clear_loose_ref_cache(&ref_cache); cleanup: + transaction->status = ret ? REF_TRANSACTION_ERROR + : REF_TRANSACTION_CLOSED; + for (i = 0; i < n; i++) if (updates[i]->lock) unlock_ref(updates[i]->lock);
--
2.0.0.rc1.351.g4d2c8e4