diff --git a/include/wsrep/chrono.hpp b/include/wsrep/chrono.hpp index e657616..14961d7 100644 --- a/include/wsrep/chrono.hpp +++ b/include/wsrep/chrono.hpp @@ -24,7 +24,7 @@ */ #ifndef WSREP_CHRONO_HPP -#define WSREP_CHORNO_HPP +#define WSREP_CHRONO_HPP #include diff --git a/include/wsrep/client_state.hpp b/include/wsrep/client_state.hpp index 4c2f4a8..0299cf9 100644 --- a/include/wsrep/client_state.hpp +++ b/include/wsrep/client_state.hpp @@ -1008,6 +1008,15 @@ namespace wsrep enum wsrep::provider::status status = wsrep::provider::success); + // Poll provider::enter_toi() until return status from provider + // does not indicate certification failure, timeout expires + // or client is interrupted. + enum wsrep::provider::status + poll_enter_toi(wsrep::unique_lock& lock, + const wsrep::key_array& keys, + const wsrep::const_buffer& buffer, + int flags, + std::chrono::time_point wait_until); void enter_toi_common(wsrep::unique_lock&); void leave_toi_common(); diff --git a/src/client_state.cpp b/src/client_state.cpp index 0b63bae..d969c50 100644 --- a/src/client_state.cpp +++ b/src/client_state.cpp @@ -21,6 +21,7 @@ #include "wsrep/compiler.hpp" #include "wsrep/logger.hpp" +#include // usleep() #include #include @@ -330,6 +331,32 @@ void wsrep::client_state::disable_streaming() // TOI // ////////////////////////////////////////////////////////////////////////////// +enum wsrep::provider::status +wsrep::client_state::poll_enter_toi( + wsrep::unique_lock& lock, + const wsrep::key_array& keys, + const wsrep::const_buffer& buffer, + int flags, + std::chrono::time_point wait_until) +{ + enum wsrep::provider::status status; + do + { + lock.unlock(); + status = provider().enter_toi(id_, keys, buffer, toi_meta_, flags); + if (status == wsrep::provider::error_certification_failed) + { + ::usleep(100000); + } + lock.lock(); + } + while (status == wsrep::provider::error_certification_failed && + wait_until.time_since_epoch().count() && + wait_until < wsrep::clock::now() && + not client_service_.interrupted(lock)); + return status; +} + void wsrep::client_state::enter_toi_common( wsrep::unique_lock& lock) { @@ -347,22 +374,13 @@ int wsrep::client_state::enter_toi_local(const wsrep::key_array& keys, assert(mode_ == m_local); int ret; - enum wsrep::provider::status status; wsrep::unique_lock lock(mutex_); - // Poll until timeout expires or the client is interrupted. - do - { - lock.unlock(); - status = provider().enter_toi(id_, keys, buffer, toi_meta_, - wsrep::provider::flag::start_transaction | - wsrep::provider::flag::commit); - lock.lock(); - } - while (status == wsrep::provider::error_certification_failed && - wait_until.time_since_epoch().count() && - wait_until < wsrep::clock::now() && - not client_service_.interrupted(lock)); + auto const status(poll_enter_toi( + lock, keys, buffer, + wsrep::provider::flag::start_transaction | + wsrep::provider::flag::commit, + wait_until)); switch (status) { case wsrep::provider::success: @@ -485,20 +503,11 @@ int wsrep::client_state::begin_nbo_phase_one( assert(mode_ == m_local); assert(toi_mode_ == m_undefined); - enum wsrep::provider::status status; - // Poll until timeout expires or the client is interrupted. - do - { - lock.unlock(); - status = provider().enter_toi(id_, keys, buffer, toi_meta_, - wsrep::provider::flag::start_transaction); - lock.lock(); - } - while (status == wsrep::provider::error_certification_failed && - wait_until.time_since_epoch().count() && - wait_until < wsrep::clock::now() && - not client_service_.interrupted(lock)); int ret; + auto const status(poll_enter_toi( + lock, keys, buffer, + wsrep::provider::flag::start_transaction, + wait_until)); switch (status) { case wsrep::provider::success: