[PATCH] txn: convert txn flags into bit mask
Vladimir Davydov
vdavydov.dev at gmail.com
Mon Jul 29 13:52:26 MSK 2019
---
https://github.com/tarantool/tarantool/commits/dv/txn-flags
src/box/txn.c | 35 +++++++++++++++++------------------
src/box/txn.h | 38 ++++++++++++++++++++++----------------
2 files changed, 39 insertions(+), 34 deletions(-)
diff --git a/src/box/txn.c b/src/box/txn.c
index c7d01b2e..93cc24c2 100644
--- a/src/box/txn.c
+++ b/src/box/txn.c
@@ -197,10 +197,7 @@ txn_begin()
txn->n_new_rows = 0;
txn->n_local_rows = 0;
txn->n_applier_rows = 0;
- txn->has_triggers = false;
- txn->is_done = false;
- txn->can_yield = true;
- txn->is_aborted_by_yield = false;
+ txn->flags = TXN_CAN_YIELD;
txn->in_sub_stmt = 0;
txn->id = ++tsn;
txn->signature = -1;
@@ -396,13 +393,13 @@ txn_complete(struct txn *txn)
/* Undo the transaction. */
if (txn->engine)
engine_rollback(txn->engine, txn);
- if (txn->has_triggers)
+ if (txn->flags & TXN_HAS_TRIGGERS)
txn_run_rollback_triggers(txn);
} else {
/* Commit the transaction. */
if (txn->engine != NULL)
engine_commit(txn->engine, txn);
- if (txn->has_triggers)
+ if (txn->flags & TXN_HAS_TRIGGERS)
txn_run_commit_triggers(txn);
double stop_tm = ev_monotonic_now(loop());
@@ -422,7 +419,7 @@ txn_complete(struct txn *txn)
if (txn->fiber == NULL)
txn_free(txn);
else {
- txn->is_done = true;
+ txn->flags |= TXN_IS_DONE;
if (txn->fiber != fiber())
/* Wake a waiting fiber up. */
fiber_wakeup(txn->fiber);
@@ -491,8 +488,8 @@ txn_write_to_wal(struct txn *txn)
static int
txn_prepare(struct txn *txn)
{
- if (txn->is_aborted_by_yield) {
- assert(!txn->can_yield);
+ if (txn->flags & TXN_IS_ABORTED_BY_YIELD) {
+ assert(!(txn->flags & TXN_CAN_YIELD));
diag_set(ClientError, ER_TRANSACTION_YIELD);
diag_log();
return -1;
@@ -518,7 +515,7 @@ txn_prepare(struct txn *txn)
return -1;
}
trigger_clear(&txn->fiber_on_stop);
- if (!txn->can_yield)
+ if (!(txn->flags & TXN_CAN_YIELD))
trigger_clear(&txn->fiber_on_yield);
return 0;
}
@@ -558,7 +555,7 @@ txn_commit(struct txn *txn)
* In case of non-yielding journal the transaction could already
* be done and there is nothing to wait in such cases.
*/
- if (!txn->is_done) {
+ if (!(txn->flags & TXN_IS_DONE)) {
bool cancellable = fiber_set_cancellable(false);
fiber_yield();
fiber_set_cancellable(cancellable);
@@ -586,7 +583,7 @@ txn_rollback(struct txn *txn)
{
assert(txn == in_txn());
trigger_clear(&txn->fiber_on_stop);
- if (!txn->can_yield)
+ if (!(txn->flags & TXN_CAN_YIELD))
trigger_clear(&txn->fiber_on_yield);
txn->signature = -1;
txn_complete(txn);
@@ -607,11 +604,13 @@ void
txn_can_yield(struct txn *txn, bool set)
{
assert(txn == in_txn());
- assert(txn->can_yield != set);
- txn->can_yield = set;
if (set) {
+ assert(!(txn->flags & TXN_CAN_YIELD));
+ txn->flags |= TXN_CAN_YIELD;
trigger_clear(&txn->fiber_on_yield);
} else {
+ assert(txn->flags & TXN_CAN_YIELD);
+ txn->flags &= ~TXN_CAN_YIELD;
trigger_create(&txn->fiber_on_yield, txn_on_yield, NULL, NULL);
trigger_add(&fiber()->on_yield, &txn->fiber_on_yield);
}
@@ -781,11 +780,11 @@ txn_on_yield(struct trigger *trigger, void *event)
(void) trigger;
(void) event;
struct txn *txn = in_txn();
- assert(txn != NULL && !txn->can_yield);
+ assert(txn != NULL && !(txn->flags & TXN_CAN_YIELD));
txn_rollback_to_svp(txn, NULL);
- if (txn->has_triggers) {
+ if (txn->flags & TXN_HAS_TRIGGERS) {
txn_run_rollback_triggers(txn);
- txn->has_triggers = false;
+ txn->flags &= ~TXN_HAS_TRIGGERS;
}
- txn->is_aborted_by_yield = true;
+ txn->flags |= TXN_IS_ABORTED_BY_YIELD;
}
diff --git a/src/box/txn.h b/src/box/txn.h
index 2d5dea21..d5dceaed 100644
--- a/src/box/txn.h
+++ b/src/box/txn.h
@@ -51,6 +51,24 @@ struct tuple;
struct xrow_header;
struct Vdbe;
+/** Allowed values for txn::flags. */
+enum {
+ /** Transaction has been processed. */
+ TXN_IS_DONE = 1 << 0,
+ /**
+ * Transaction has been aborted by fiber yield so
+ * should be rolled back at commit.
+ */
+ TXN_IS_ABORTED_BY_YIELD = 1 << 1,
+ /**
+ * fiber_yield() is allowed inside the transaction.
+ * See txn_can_yield() for more details.
+ */
+ TXN_CAN_YIELD = 1 << 2,
+ /** on_commit and/or on_rollback list is not empty. */
+ TXN_HAS_TRIGGERS = 1 << 3,
+};
+
enum {
/**
* Maximum recursion depth for on_replace triggers.
@@ -160,20 +178,8 @@ struct txn {
* already assigned LSN.
*/
int n_applier_rows;
- /* True when transaction is processed. */
- bool is_done;
- /**
- * True if the transaction was aborted so should be
- * rolled back at commit.
- */
- bool is_aborted_by_yield;
- /**
- * True if yields are allowed inside a transaction,
- * see txn_can_yield().
- */
- bool can_yield;
- /** True if on_commit and on_rollback lists are non-empty. */
- bool has_triggers;
+ /** Transaction flags, see TXN_*. */
+ unsigned flags;
/** The number of active nested statement-level transactions. */
int8_t in_sub_stmt;
/**
@@ -260,10 +266,10 @@ txn_write(struct txn *txn);
static inline void
txn_init_triggers(struct txn *txn)
{
- if (txn->has_triggers == false) {
+ if (!(txn->flags & TXN_HAS_TRIGGERS)) {
rlist_create(&txn->on_commit);
rlist_create(&txn->on_rollback);
- txn->has_triggers = true;
+ txn->flags |= TXN_HAS_TRIGGERS;
}
}
--
2.20.1
More information about the Tarantool-patches
mailing list