1
0
mirror of https://github.com/codership/wsrep-lib.git synced 2025-07-25 21:41:56 +03:00

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.
This commit is contained in:
Teemu Ollakka
2019-02-18 09:02:33 +02:00
parent 8c2daa7e3d
commit 92024c7d50

View File

@ -431,7 +431,9 @@ int wsrep::transaction::before_commit()
{ {
ret = 0; ret = 0;
} }
lock.unlock();
ret = ret || provider().commit_order_enter(ws_handle_, ws_meta_); ret = ret || provider().commit_order_enter(ws_handle_, ws_meta_);
lock.lock();
if (ret) if (ret)
{ {
state(lock, s_must_abort); state(lock, s_must_abort);
@ -749,7 +751,9 @@ int wsrep::transaction::after_statement()
{ {
if (ordered()) if (ordered())
{ {
lock.unlock();
ret = provider().commit_order_enter(ws_handle_, ws_meta_); ret = provider().commit_order_enter(ws_handle_, ws_meta_);
lock.lock();
if (ret == 0) if (ret == 0)
{ {
provider().commit_order_leave(ws_handle_, ws_meta_); provider().commit_order_leave(ws_handle_, ws_meta_);
@ -785,7 +789,9 @@ void wsrep::transaction::after_applying()
// been done. // been done.
if (state_ == s_aborted && ordered()) if (state_ == s_aborted && ordered())
{ {
lock.unlock();
int ret(provider().commit_order_enter(ws_handle_, ws_meta_)); int ret(provider().commit_order_enter(ws_handle_, ws_meta_));
lock.lock();
if (ret == 0) if (ret == 0)
{ {
provider().commit_order_leave(ws_handle_, ws_meta_); provider().commit_order_leave(ws_handle_, ws_meta_);