position_in_partition: make operator= exception-safe

The copy assignment operator of _ck can throw
after _type and _bound_weight have already been changed.
This leaves position_in_partition in an inconsistent state,
potentially leading to various weird symptoms.

The problem was witnessed by test_exception_safety_of_reads.
Specifically: in cache_flat_mutation_reader::add_to_buffer,
which requires the assignment to _lower_bound to be exception-safe.

The easy fix is to perform the only potentially-throwing step first.

Fixes #15822

Closes scylladb/scylladb#15864
This commit is contained in:
Michał Chojnowski
2023-10-27 13:04:36 +02:00
committed by Avi Kivity
parent 5807ef0bb7
commit 93ea3d41d8

View File

@@ -360,14 +360,19 @@ public:
}
}
// Strong exception guarantees.
position_in_partition& operator=(position_in_partition_view view) {
_type = view._type;
_bound_weight = view._bound_weight;
// The copy assigment to _ck can throw (because it allocates),
// but assignments to _type and _bound_weight can't throw.
// Thus, to achieve strong exception guarantees,
// we only need to perform the _ck assigmnent before others.
if (view._ck) {
_ck = *view._ck;
} else {
_ck.reset();
}
_type = view._type;
_bound_weight = view._bound_weight;
return *this;
}