mirror of
https://github.com/codership/wsrep-lib.git
synced 2025-07-03 16:22:35 +03:00
In order to avoid potential deadlocks, release client_state lock when
calling server state methods which may acquire server_state mutex. Fixed compilation errors in release mode.
This commit is contained in:
@ -88,6 +88,7 @@
|
|||||||
#include "view.hpp"
|
#include "view.hpp"
|
||||||
#include "transaction_id.hpp"
|
#include "transaction_id.hpp"
|
||||||
#include "provider.hpp"
|
#include "provider.hpp"
|
||||||
|
#include "compiler.hpp"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -488,7 +489,8 @@ namespace wsrep
|
|||||||
return state(lock);
|
return state(lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum state state(wsrep::unique_lock<wsrep::mutex>& lock) const
|
enum state state(wsrep::unique_lock<wsrep::mutex>&
|
||||||
|
lock WSREP_UNUSED) const
|
||||||
{
|
{
|
||||||
assert(lock.owns_lock());
|
assert(lock.owns_lock());
|
||||||
return state_;
|
return state_;
|
||||||
|
@ -18,8 +18,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/** @file transaction.hpp */
|
/** @file transaction.hpp */
|
||||||
#ifndef WSREP_TRANSACTION_CONTEXT_HPP
|
#ifndef WSREP_TRANSACTION_HPP
|
||||||
#define WSREP_TRANSACTION_CONTEXT_HPP
|
#define WSREP_TRANSACTION_HPP
|
||||||
|
|
||||||
#include "provider.hpp"
|
#include "provider.hpp"
|
||||||
#include "server_state.hpp"
|
#include "server_state.hpp"
|
||||||
@ -175,7 +175,7 @@ namespace wsrep
|
|||||||
int certify_fragment(wsrep::unique_lock<wsrep::mutex>&);
|
int certify_fragment(wsrep::unique_lock<wsrep::mutex>&);
|
||||||
int certify_commit(wsrep::unique_lock<wsrep::mutex>&);
|
int certify_commit(wsrep::unique_lock<wsrep::mutex>&);
|
||||||
int append_sr_keys_for_commit();
|
int append_sr_keys_for_commit();
|
||||||
void streaming_rollback();
|
void streaming_rollback(wsrep::unique_lock<wsrep::mutex>&);
|
||||||
void clear_fragments();
|
void clear_fragments();
|
||||||
void cleanup();
|
void cleanup();
|
||||||
void debug_log_state(const char*) const;
|
void debug_log_state(const char*) const;
|
||||||
@ -227,4 +227,4 @@ namespace wsrep
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // WSREP_TRANSACTION_CONTEXT_HPP
|
#endif // WSREP_TRANSACTION_HPP
|
||||||
|
@ -314,13 +314,12 @@ int wsrep::client_state::enter_toi(const wsrep::ws_meta& ws_meta)
|
|||||||
|
|
||||||
int wsrep::client_state::leave_toi()
|
int wsrep::client_state::leave_toi()
|
||||||
{
|
{
|
||||||
int ret;
|
int ret(0);
|
||||||
if (toi_mode_ == m_local)
|
if (toi_mode_ == m_local)
|
||||||
{
|
{
|
||||||
switch (provider().leave_toi(id_))
|
switch (provider().leave_toi(id_))
|
||||||
{
|
{
|
||||||
case wsrep::provider::success:
|
case wsrep::provider::success:
|
||||||
ret = 0;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
|
@ -929,7 +929,8 @@ int wsrep::server_state::desync(wsrep::unique_lock<wsrep::mutex>& lock)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wsrep::server_state::resync(wsrep::unique_lock<wsrep::mutex>& lock)
|
void wsrep::server_state::resync(wsrep::unique_lock<wsrep::mutex>&
|
||||||
|
lock WSREP_UNUSED)
|
||||||
{
|
{
|
||||||
assert(lock.owns_lock());
|
assert(lock.owns_lock());
|
||||||
assert(desync_count_ > 0);
|
assert(desync_count_ > 0);
|
||||||
|
@ -520,7 +520,9 @@ int wsrep::transaction::after_commit()
|
|||||||
client_state_.mode() == wsrep::client_state::m_high_priority);
|
client_state_.mode() == wsrep::client_state::m_high_priority);
|
||||||
if (client_state_.mode() == wsrep::client_state::m_local)
|
if (client_state_.mode() == wsrep::client_state::m_local)
|
||||||
{
|
{
|
||||||
|
lock.unlock();
|
||||||
client_state_.server_state_.stop_streaming_client(&client_state_);
|
client_state_.server_state_.stop_streaming_client(&client_state_);
|
||||||
|
lock.lock();
|
||||||
}
|
}
|
||||||
clear_fragments();
|
clear_fragments();
|
||||||
}
|
}
|
||||||
@ -573,7 +575,7 @@ int wsrep::transaction::before_rollback()
|
|||||||
// Voluntary rollback
|
// Voluntary rollback
|
||||||
if (is_streaming())
|
if (is_streaming())
|
||||||
{
|
{
|
||||||
streaming_rollback();
|
streaming_rollback(lock);
|
||||||
}
|
}
|
||||||
state(lock, s_aborting);
|
state(lock, s_aborting);
|
||||||
break;
|
break;
|
||||||
@ -586,7 +588,7 @@ int wsrep::transaction::before_rollback()
|
|||||||
{
|
{
|
||||||
if (is_streaming())
|
if (is_streaming())
|
||||||
{
|
{
|
||||||
streaming_rollback();
|
streaming_rollback(lock);
|
||||||
}
|
}
|
||||||
state(lock, s_aborting);
|
state(lock, s_aborting);
|
||||||
}
|
}
|
||||||
@ -594,14 +596,14 @@ int wsrep::transaction::before_rollback()
|
|||||||
case s_cert_failed:
|
case s_cert_failed:
|
||||||
if (is_streaming())
|
if (is_streaming())
|
||||||
{
|
{
|
||||||
streaming_rollback();
|
streaming_rollback(lock);
|
||||||
}
|
}
|
||||||
state(lock, s_aborting);
|
state(lock, s_aborting);
|
||||||
break;
|
break;
|
||||||
case s_aborting:
|
case s_aborting:
|
||||||
if (is_streaming())
|
if (is_streaming())
|
||||||
{
|
{
|
||||||
streaming_rollback();
|
streaming_rollback(lock);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case s_must_replay:
|
case s_must_replay:
|
||||||
@ -899,7 +901,7 @@ bool wsrep::transaction::bf_abort(
|
|||||||
if (client_state_.mode() == wsrep::client_state::m_local &&
|
if (client_state_.mode() == wsrep::client_state::m_local &&
|
||||||
is_streaming() && state() == s_executing)
|
is_streaming() && state() == s_executing)
|
||||||
{
|
{
|
||||||
streaming_rollback();
|
streaming_rollback(lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((client_state_.state() == wsrep::client_state::s_idle &&
|
if ((client_state_.state() == wsrep::client_state::s_idle &&
|
||||||
@ -918,8 +920,10 @@ bool wsrep::transaction::bf_abort(
|
|||||||
state(lock, wsrep::transaction::s_aborting);
|
state(lock, wsrep::transaction::s_aborting);
|
||||||
if (client_state_.mode() == wsrep::client_state::m_high_priority)
|
if (client_state_.mode() == wsrep::client_state::m_high_priority)
|
||||||
{
|
{
|
||||||
|
lock.unlock();
|
||||||
client_state_.server_state().stop_streaming_applier(
|
client_state_.server_state().stop_streaming_applier(
|
||||||
server_id_, id_);
|
server_id_, id_);
|
||||||
|
lock.lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
@ -1170,11 +1174,13 @@ int wsrep::transaction::certify_fragment(
|
|||||||
{
|
{
|
||||||
if (is_streaming() == false)
|
if (is_streaming() == false)
|
||||||
{
|
{
|
||||||
|
lock.unlock();
|
||||||
client_state_.server_state_.stop_streaming_client(&client_state_);
|
client_state_.server_state_.stop_streaming_client(&client_state_);
|
||||||
|
lock.lock();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
streaming_rollback();
|
streaming_rollback(lock);
|
||||||
}
|
}
|
||||||
if (state_ != s_must_abort)
|
if (state_ != s_must_abort)
|
||||||
{
|
{
|
||||||
@ -1186,7 +1192,7 @@ int wsrep::transaction::certify_fragment(
|
|||||||
{
|
{
|
||||||
if (is_streaming())
|
if (is_streaming())
|
||||||
{
|
{
|
||||||
streaming_rollback();
|
streaming_rollback(lock);
|
||||||
}
|
}
|
||||||
client_state_.override_error(wsrep::e_deadlock_error, cert_ret);
|
client_state_.override_error(wsrep::e_deadlock_error, cert_ret);
|
||||||
ret = 1;
|
ret = 1;
|
||||||
@ -1389,7 +1395,7 @@ int wsrep::transaction::append_sr_keys_for_commit()
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wsrep::transaction::streaming_rollback()
|
void wsrep::transaction::streaming_rollback(wsrep::unique_lock<wsrep::mutex>& lock)
|
||||||
{
|
{
|
||||||
debug_log_state("streaming_rollback enter");
|
debug_log_state("streaming_rollback enter");
|
||||||
assert(state_ != s_must_replay);
|
assert(state_ != s_must_replay);
|
||||||
@ -1399,7 +1405,9 @@ void wsrep::transaction::streaming_rollback()
|
|||||||
{
|
{
|
||||||
if (bf_aborted_in_total_order_)
|
if (bf_aborted_in_total_order_)
|
||||||
{
|
{
|
||||||
|
lock.unlock();
|
||||||
client_state_.server_state_.stop_streaming_client(&client_state_);
|
client_state_.server_state_.stop_streaming_client(&client_state_);
|
||||||
|
lock.lock();
|
||||||
streaming_context_.rolled_back(id_);
|
streaming_context_.rolled_back(id_);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1409,9 +1417,10 @@ void wsrep::transaction::streaming_rollback()
|
|||||||
// Adopt transaction will copy fragment set and appropriate
|
// Adopt transaction will copy fragment set and appropriate
|
||||||
// meta data. Mark current transaction streaming context
|
// meta data. Mark current transaction streaming context
|
||||||
// rolled back.
|
// rolled back.
|
||||||
|
lock.unlock();
|
||||||
client_state_.server_state_.convert_streaming_client_to_applier(
|
client_state_.server_state_.convert_streaming_client_to_applier(
|
||||||
&client_state_);
|
&client_state_);
|
||||||
|
lock.lock();
|
||||||
streaming_context_.cleanup();
|
streaming_context_.cleanup();
|
||||||
streaming_context_.rolled_back(id_);
|
streaming_context_.rolled_back(id_);
|
||||||
enum wsrep::provider::status ret;
|
enum wsrep::provider::status ret;
|
||||||
|
Reference in New Issue
Block a user