mirror of
https://github.com/codership/wsrep-lib.git
synced 2025-07-30 07:23:07 +03:00
Postpone streaming_context cleanup into after_rollback()
Streaming_context was cleaned up in streaming_rollback(), which could cause clearing fragment seqno vector while it was still accessed by the owning thread, causing undefined behavior. Fixed by postponing streaming_context cleanup for BF aborted SR transactions to always happen in after_rollback().
This commit is contained in:
@ -1961,12 +1961,19 @@ void wsrep::transaction::streaming_rollback(
|
|||||||
|
|
||||||
if (streaming_context_.rolled_back() == false)
|
if (streaming_context_.rolled_back() == false)
|
||||||
{
|
{
|
||||||
|
// Note that streaming_context_ must not be cleaned up in this
|
||||||
|
// method. This is because the owning thread may still be executing
|
||||||
|
// fragment removal on commit, which will access fragment
|
||||||
|
// vector in streaming context. Clearing streaming context
|
||||||
|
// here may cause owning thread to access memory which was
|
||||||
|
// already freed. Cleanup for streaming_context_ will happen
|
||||||
|
// in after_rollback().
|
||||||
|
|
||||||
if (bf_aborted_in_total_order_)
|
if (bf_aborted_in_total_order_)
|
||||||
{
|
{
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
server_service_.debug_sync("wsrep_streaming_rollback");
|
server_service_.debug_sync("wsrep_streaming_rollback");
|
||||||
client_state_.server_state_.stop_streaming_client(&client_state_);
|
client_state_.server_state_.stop_streaming_client(&client_state_);
|
||||||
// Fragments are removed in after_rollback().
|
|
||||||
lock.lock();
|
lock.lock();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1980,7 +1987,6 @@ void wsrep::transaction::streaming_rollback(
|
|||||||
client_state_.server_state_.convert_streaming_client_to_applier(
|
client_state_.server_state_.convert_streaming_client_to_applier(
|
||||||
&client_state_);
|
&client_state_);
|
||||||
lock.lock();
|
lock.lock();
|
||||||
streaming_context_.cleanup();
|
|
||||||
|
|
||||||
enum wsrep::provider::status status(provider().rollback(id_));
|
enum wsrep::provider::status status(provider().rollback(id_));
|
||||||
if (status)
|
if (status)
|
||||||
|
Reference in New Issue
Block a user