diff --git a/include/wsrep/client_context.hpp b/include/wsrep/client_context.hpp index 8dce5d3..7ba67da 100644 --- a/include/wsrep/client_context.hpp +++ b/include/wsrep/client_context.hpp @@ -262,14 +262,16 @@ namespace wsrep } int before_prepare() { + wsrep::unique_lock lock(mutex_); assert(state_ == s_exec); - return transaction_.before_prepare(); + return transaction_.before_prepare(lock); } int after_prepare() { + wsrep::unique_lock lock(mutex_); assert(state_ == s_exec); - return transaction_.after_prepare(); + return transaction_.after_prepare(lock); } int before_commit() diff --git a/include/wsrep/transaction_context.hpp b/include/wsrep/transaction_context.hpp index 944be89..7e6e9d5 100644 --- a/include/wsrep/transaction_context.hpp +++ b/include/wsrep/transaction_context.hpp @@ -98,9 +98,9 @@ namespace wsrep int after_row(); - int before_prepare(); + int before_prepare(wsrep::unique_lock&); - int after_prepare(); + int after_prepare(wsrep::unique_lock&); int before_commit(); diff --git a/src/transaction_context.cpp b/src/transaction_context.cpp index b31c925..0d8f097 100644 --- a/src/transaction_context.cpp +++ b/src/transaction_context.cpp @@ -115,11 +115,11 @@ int wsrep::transaction_context::after_row() return 0; } -int wsrep::transaction_context::before_prepare() +int wsrep::transaction_context::before_prepare( + wsrep::unique_lock& lock) { + assert(lock.owns_lock()); int ret(0); - - wsrep::unique_lock lock(client_context_.mutex()); debug_log_state("before_prepare_enter"); assert(state() == s_executing || state() == s_must_abort); @@ -168,10 +168,11 @@ int wsrep::transaction_context::before_prepare() return ret; } -int wsrep::transaction_context::after_prepare() +int wsrep::transaction_context::after_prepare( + wsrep::unique_lock& lock) { + assert(lock.owns_lock()); int ret(1); - wsrep::unique_lock lock(client_context_.mutex()); debug_log_state("after_prepare_enter"); assert(state() == s_preparing || state() == s_must_abort); if (state() == s_must_abort) @@ -185,7 +186,7 @@ int wsrep::transaction_context::after_prepare() { case wsrep::client_context::m_replicating: ret = certify_commit(lock); - assert((ret == 0 || state() == s_committing) || + assert((ret == 0 && state() == s_committing) || (state() == s_must_abort || state() == s_must_replay || state() == s_cert_failed)); @@ -226,12 +227,10 @@ int wsrep::transaction_context::before_commit() } break; case wsrep::client_context::m_replicating: - - // Commit is one phase - before/after prepare was not called if (state() == s_executing) { - ret = certify_commit(lock); - assert((ret == 0 || state() == s_committing) + ret = before_prepare(lock) || after_prepare(lock); + assert((ret == 0 && state() == s_committing) || (state() == s_must_abort || state() == s_must_replay || @@ -278,7 +277,6 @@ int wsrep::transaction_context::before_commit() assert(0); break; } - } break; case wsrep::client_context::m_applier: diff --git a/test/fake_client_context.cpp b/test/fake_client_context.cpp index ebc8966..ac00151 100644 --- a/test/fake_client_context.cpp +++ b/test/fake_client_context.cpp @@ -19,11 +19,11 @@ int wsrep::fake_client_context::commit() int ret(0); if (do_2pc()) { - if (transaction_.before_prepare()) + if (before_prepare()) { ret = 1; } - else if (transaction_.after_prepare()) + else if (after_prepare()) { ret = 1; }