diff --git a/include/wsrep/client_state.hpp b/include/wsrep/client_state.hpp index 9f87176..a9d36c4 100644 --- a/include/wsrep/client_state.hpp +++ b/include/wsrep/client_state.hpp @@ -489,6 +489,31 @@ namespace wsrep transaction_.adopt(transaction); } + /** + * Clone enough state from another transaction so that replaing will + * be possible with a transaction contained in this client state. + * Method after_replay() must be used to inject the state after + * replaying back to this client state. + * + * @param transaction Transaction which is to be replied in this + * client state + */ + void clone_transaction_for_replay(const wsrep::transaction& transaction) + { + // assert(mode_ == m_high_priority); + transaction_.clone_for_replay(transaction); + } + + /** + * Copy state from another transaction context after replay. + * + * @param transaction Transaction which was used for replaying. + */ + void after_replay(const wsrep::transaction& transaction) + { + transaction_.after_replay(transaction); + } + /** @name Non-transactional operations */ /** @{*/ diff --git a/include/wsrep/transaction.hpp b/include/wsrep/transaction.hpp index 5284180..b8fadb9 100644 --- a/include/wsrep/transaction.hpp +++ b/include/wsrep/transaction.hpp @@ -168,6 +168,11 @@ namespace wsrep wsrep::seqno bf_seqno); bool total_order_bf_abort(wsrep::unique_lock&, wsrep::seqno bf_seqno); + + void clone_for_replay(const wsrep::transaction& other); + + void after_replay(const wsrep::transaction& other); + bool bf_aborted() const { return (bf_abort_client_state_ != 0); diff --git a/src/transaction.cpp b/src/transaction.cpp index 46f24b3..ff4074f 100644 --- a/src/transaction.cpp +++ b/src/transaction.cpp @@ -935,6 +935,24 @@ bool wsrep::transaction::total_order_bf_abort( return ret; } +void wsrep::transaction::clone_for_replay(const wsrep::transaction& other) +{ + assert(other.state() == s_replaying); + id_ = other.id_; + ws_handle_ = other.ws_handle_; + ws_meta_ = other.ws_meta_; + streaming_context_ = other.streaming_context_; + state_ = s_replaying; +} + +void wsrep::transaction::after_replay(const wsrep::transaction& other) +{ + // Other must have been terminated + assert(other.state() == s_committed || other.state() == s_aborted); + state_ = other.state(); + clear_fragments(); +} + //////////////////////////////////////////////////////////////////////////////// // Private // ////////////////////////////////////////////////////////////////////////////////