From 92024c7d502b716c8c0ca5e2b9524b43d3a5378c Mon Sep 17 00:00:00 2001 From: Teemu Ollakka Date: Mon, 18 Feb 2019 09:02:33 +0200 Subject: [PATCH] codership/wsrep-lib#83 Release lock before commit_order_enter() A high priority transaction T2 which calls commit_order_enter() with client_state mutex locked may cause a deadlock if an another high priority transaction T1 ordered before tries to access the transaction T2 state. As a fix, make sure that commit_order_enter() is never called with client_state mutex locked. --- src/transaction.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/transaction.cpp b/src/transaction.cpp index b5fa771..e17694d 100644 --- a/src/transaction.cpp +++ b/src/transaction.cpp @@ -431,7 +431,9 @@ int wsrep::transaction::before_commit() { ret = 0; } + lock.unlock(); ret = ret || provider().commit_order_enter(ws_handle_, ws_meta_); + lock.lock(); if (ret) { state(lock, s_must_abort); @@ -749,7 +751,9 @@ int wsrep::transaction::after_statement() { if (ordered()) { + lock.unlock(); ret = provider().commit_order_enter(ws_handle_, ws_meta_); + lock.lock(); if (ret == 0) { provider().commit_order_leave(ws_handle_, ws_meta_); @@ -785,7 +789,9 @@ void wsrep::transaction::after_applying() // been done. if (state_ == s_aborted && ordered()) { + lock.unlock(); int ret(provider().commit_order_enter(ws_handle_, ws_meta_)); + lock.lock(); if (ret == 0) { provider().commit_order_leave(ws_handle_, ws_meta_);