[Tarantool-patches] [PATCH 3/7] txn: detach transaction from fiber.
mechanik20051988
mechanik20051988 at tarantool.org
Thu Aug 5 21:17:41 MSK 2021
From: mechanik20051988 <mechanik20.05.1988 at gmail.com>
Detach transaction from fiber: now it is possible to start
transaction in fiber, save the pointer to it in some place
independent from the fiber and then restore it other fiber.
For this purpose `fiber_on_stop` and `fiber_on_yield` triggers
was changed: previously they received pointer to transaction
from the fiber storage, now they receive it as their argument,
because fiber storage can be already empty when they called.
Also implement function `txn_detach`, which clear `fiber_on_stop`
and `fiber_on_yeild` triggers. Detached transaction does not
rollback in case when fiber stopped, but can be aborted in case
it does not support yeild.
Path of #5860
---
src/box/txn.c | 29 ++++++++++++++++++++++-------
src/box/txn.h | 11 +++++++++++
2 files changed, 33 insertions(+), 7 deletions(-)
diff --git a/src/box/txn.c b/src/box/txn.c
index b80e722a4..de6a7f37d 100644
--- a/src/box/txn.c
+++ b/src/box/txn.c
@@ -302,8 +302,9 @@ txn_begin(void)
rlist_create(&txn->savepoints);
txn->fiber = NULL;
fiber_set_txn(fiber(), txn);
- /* fiber_on_yield is initialized by engine on demand */
- trigger_create(&txn->fiber_on_stop, txn_on_stop, NULL, NULL);
+ trigger_create(&txn->fiber_on_yield, txn_on_yield, txn, NULL);
+ trigger_create(&txn->fiber_on_stop, txn_on_stop, txn, NULL);
+ /* fiber_on_yield is added by engine on demand */
trigger_add(&fiber()->on_stop, &txn->fiber_on_stop);
/*
* By default all transactions may yield.
@@ -1016,7 +1017,6 @@ txn_can_yield(struct txn *txn, bool set)
trigger_clear(&txn->fiber_on_yield);
} else if (!set && could) {
txn_clear_flags(txn, TXN_CAN_YIELD);
- trigger_create(&txn->fiber_on_yield, txn_on_yield, NULL, NULL);
trigger_add(&fiber()->on_yield, &txn->fiber_on_yield);
}
return could;
@@ -1216,9 +1216,8 @@ txn_savepoint_release(struct txn_savepoint *svp)
static int
txn_on_stop(struct trigger *trigger, void *event)
{
- (void) trigger;
(void) event;
- struct txn *txn = in_txn();
+ struct txn *txn = trigger->data;
assert(txn->signature == TXN_SIGNATURE_UNKNOWN);
txn->signature = TXN_SIGNATURE_ROLLBACK;
txn_rollback(txn);
@@ -1246,12 +1245,28 @@ txn_on_stop(struct trigger *trigger, void *event)
static int
txn_on_yield(struct trigger *trigger, void *event)
{
- (void) trigger;
(void) event;
- struct txn *txn = in_txn();
+ struct txn *txn = trigger->data;
assert(txn != NULL);
assert(!txn_has_flag(txn, TXN_CAN_YIELD));
txn_rollback_to_svp(txn, NULL);
txn_set_flags(txn, TXN_IS_ABORTED_BY_YIELD);
return 0;
}
+
+struct txn *
+txn_detach(void)
+{
+ struct txn *txn = in_txn();
+ if (txn == NULL)
+ return NULL;
+ if (!txn_has_flag(txn, TXN_CAN_YIELD)) {
+ struct trigger trigger;
+ trigger.data = txn;
+ txn_on_yield(&trigger, NULL);
+ }
+ trigger_clear(&txn->fiber_on_yield);
+ trigger_clear(&txn->fiber_on_stop);
+ fiber_set_txn(fiber(), NULL);
+ return txn;
+}
\ No newline at end of file
diff --git a/src/box/txn.h b/src/box/txn.h
index 8741dc6a1..b8bba67b8 100644
--- a/src/box/txn.h
+++ b/src/box/txn.h
@@ -457,6 +457,17 @@ fiber_set_txn(struct fiber *fiber, struct txn *txn)
fiber->storage.txn = txn;
}
+/**
+ * Detach transaction from fiber.
+ * By default if the fiber is stopped the transaction
+ * started in this fiber is rollback. This function
+ * detaches transaction from fiber, leaving it alive
+ * after fiber is stopped.
+ * @pre txn == in_txn()
+ */
+struct txn *
+txn_detach(void);
+
/**
* Start a transaction explicitly.
* @pre no transaction is active
--
2.20.1
More information about the Tarantool-patches
mailing list