From 173c2ca95c464e7441344a68de042caf40d06943 Mon Sep 17 00:00:00 2001 From: Rick van Rein Date: Tue, 4 Jul 2017 10:10:42 +0100 Subject: [PATCH] Improved transaction handling in PulleyBack plugin (poolback) - Collected failures within a transaction as TXN_ABORT transactional state - When commit fails, enact a rollback and remove transaction - When prepare fails, still need to invoke rollback (see documentation) --- pulleyback/api.c | 21 +++++++++++++++++++-- test/Makefile | 4 +++- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/pulleyback/api.c b/pulleyback/api.c index 4158759..82205f3 100644 --- a/pulleyback/api.c +++ b/pulleyback/api.c @@ -87,22 +87,33 @@ static int have_txn (struct pulleyback_tlspool *self) { } self->txn_state = TXN_ACTIVE; return 1; + case TXN_ABORT: case TXN_ACTIVE: return 1; case TXN_SUCCESS: - case TXN_ABORT: // You cannot have_txn() after _prepare() assert ((self->txn_state == TXN_NONE) || (self->txn_state == TXN_ACTIVE)); return 0; } } +/* Internal method to process a negative "ok" value by switching to TXN_ABORT + */ +static int check_txn (struct pulleyback_tlspool *self, int ok) { + if (ok != 1) { + if (self->txn_state == TXN_ACTIVE) { + self->txn_state = TXN_ABORT; + } + } +} + int pulleyback_add (void *pbh, uint8_t **forkdata) { struct pulleyback_tlspool *self = (struct pulleyback_tlspool *) pbh; int ok = 1; ok = ok && have_txn (self); ok = ok && (self->txn_state == TXN_ACTIVE); ok = ok && self->update (self, forkdata, 0); + check_txn (self, ok); return ok; } @@ -112,6 +123,7 @@ int pulleyback_del (void *pbh, uint8_t **forkdata) { ok = ok && have_txn (self); ok = ok && (self->txn_state == TXN_ACTIVE); ok = ok && self->update (self, forkdata, 1); + check_txn (self, ok); return ok; } @@ -123,6 +135,7 @@ int pulleyback_reset (void *pbh) { ok = ok && have_txn (self); ok = ok && (self->txn_state == TXN_ACTIVE); ok = ok && (0 == self->db->truncate (self->db, self->txn, &count, 0)); + check_txn (self, ok); return ok; } @@ -192,9 +205,13 @@ int pulleyback_commit (void *pbh) { self->txn_state = TXN_NONE; break; case TXN_ABORT: - // Preparation fails, then the call should havae been _rollback() + // Preparation fails, then the call should have been _rollback() assert (self->txn_state != TXN_ABORT); ok = ok && 0; + // Since there actually is a transaction, roll it back + ok = ok && (0 == self->txn->abort (self->txn)); + self->txn = NULL; + self->txn_state = TXN_NONE; break; } return ok; diff --git a/test/Makefile b/test/Makefile index 8d903ca..fc07b3c 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,6 +1,6 @@ TARGETS_OFFLINE = valexprun testvalexp pulleybacksimu -TARGETS = $(TARGETS_OFFLINE) onlinecheck testonline +TARGETS = $(TARGETS_OFFLINE) onlinecheck testonline pulleybacksimu PKG_CONFIG ?= pkg-config @@ -72,6 +72,8 @@ clean: anew: clean all +anew: clean all + install: uninstall: -- 1.7.10.4