mirror of
https://github.com/codership/wsrep-lib.git
synced 2025-07-30 07:23:07 +03:00
Fix crash close_orphaned_sr_transactions()
BF abort
Some implementations of provider `bf_abort()` require `victim_ctx` to point to application side victim context. However, when total order BF abort was done from `close_orphaned_sr_transactions()`, the application side context was not available. To fix this, added an interface method `call_in_operation_context()` which allows invoking a function object with a reference to application side operation context passed in as a parameter. This method is used in `close_orphaned_sr_transactions()` to call `client_state::total_order_bf_abort()` with appropriate victim operation context.
This commit is contained in:
@ -92,6 +92,14 @@ namespace db
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void call_in_operation_context(
|
||||||
|
const std::function<void(wsrep::operation_context&)>& fn)
|
||||||
|
const override
|
||||||
|
{
|
||||||
|
wsrep::null_operation_context op;
|
||||||
|
fn(op);
|
||||||
|
}
|
||||||
|
|
||||||
void debug_sync(const char*) override { }
|
void debug_sync(const char*) override { }
|
||||||
void debug_crash(const char*) override { }
|
void debug_crash(const char*) override { }
|
||||||
private:
|
private:
|
||||||
|
@ -28,10 +28,13 @@
|
|||||||
#define WSREP_CLIENT_SERVICE_HPP
|
#define WSREP_CLIENT_SERVICE_HPP
|
||||||
|
|
||||||
#include "buffer.hpp"
|
#include "buffer.hpp"
|
||||||
|
#include "operation_context.hpp"
|
||||||
#include "provider.hpp"
|
#include "provider.hpp"
|
||||||
#include "mutex.hpp"
|
#include "mutex.hpp"
|
||||||
#include "lock.hpp"
|
#include "lock.hpp"
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
namespace wsrep
|
namespace wsrep
|
||||||
{
|
{
|
||||||
class client_service
|
class client_service
|
||||||
@ -212,6 +215,15 @@ namespace wsrep
|
|||||||
*/
|
*/
|
||||||
virtual bool is_xa_rollback() = 0;
|
virtual bool is_xa_rollback() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform a function call in operation context associated
|
||||||
|
* with the client service. The implementation must call @p fn
|
||||||
|
* with operation_context set appropriately.
|
||||||
|
*/
|
||||||
|
virtual void call_in_operation_context(
|
||||||
|
const std::function<void(wsrep::operation_context&)>& fn) const
|
||||||
|
= 0;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Debug interface
|
// Debug interface
|
||||||
//
|
//
|
||||||
|
@ -1487,6 +1487,7 @@ void wsrep::server_state::close_orphaned_sr_transactions(
|
|||||||
{
|
{
|
||||||
wsrep::client_id client_id(i->first);
|
wsrep::client_id client_id(i->first);
|
||||||
wsrep::transaction_id transaction_id(i->second->transaction().id());
|
wsrep::transaction_id transaction_id(i->second->transaction().id());
|
||||||
|
auto& client_state = *i->second;
|
||||||
// It is safe to unlock the server state temporarily here.
|
// It is safe to unlock the server state temporarily here.
|
||||||
// The processing happens inside view handler which is
|
// The processing happens inside view handler which is
|
||||||
// protected by the provider commit ordering critical
|
// protected by the provider commit ordering critical
|
||||||
@ -1497,7 +1498,15 @@ void wsrep::server_state::close_orphaned_sr_transactions(
|
|||||||
// remains unlocked, so it should not be accessed after
|
// remains unlocked, so it should not be accessed after
|
||||||
// the bf abort call.
|
// the bf abort call.
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
i->second->total_order_bf_abort(current_view_.view_seqno());
|
client_state.client_service().call_in_operation_context(
|
||||||
|
[&client_state, this](wsrep::operation_context& op_ctx)
|
||||||
|
{
|
||||||
|
wsrep::unique_lock<wsrep::mutex> lock{
|
||||||
|
client_state.mutex()
|
||||||
|
};
|
||||||
|
client_state.total_order_bf_abort(
|
||||||
|
lock, current_view_.view_seqno(), op_ctx);
|
||||||
|
});
|
||||||
lock.lock();
|
lock.lock();
|
||||||
streaming_clients_map::const_iterator found_i;
|
streaming_clients_map::const_iterator found_i;
|
||||||
while ((found_i = streaming_clients_.find(client_id)) !=
|
while ((found_i = streaming_clients_.find(client_id)) !=
|
||||||
|
@ -186,6 +186,14 @@ namespace wsrep
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void call_in_operation_context(
|
||||||
|
const std::function<void(wsrep::operation_context&)>& fn) const
|
||||||
|
WSREP_OVERRIDE
|
||||||
|
{
|
||||||
|
wsrep::null_operation_context op;
|
||||||
|
fn(op);
|
||||||
|
}
|
||||||
|
|
||||||
void debug_sync(const char* sync_point) WSREP_OVERRIDE
|
void debug_sync(const char* sync_point) WSREP_OVERRIDE
|
||||||
{
|
{
|
||||||
if (sync_point_enabled_ == sync_point)
|
if (sync_point_enabled_ == sync_point)
|
||||||
|
Reference in New Issue
Block a user