observable: allow an observable to disconnect() twice without penalty
Message-Id: <20180711070754.13286-1-avi@scylladb.com>
This commit is contained in:
@@ -22,7 +22,8 @@
|
||||
#define BOOST_TEST_MODULE observable_test
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <variant>
|
||||
#include <numeric>
|
||||
|
||||
#include "../utils/observable.hh"
|
||||
|
||||
@@ -69,3 +70,17 @@ BOOST_AUTO_TEST_CASE(test_exceptions) {
|
||||
}
|
||||
BOOST_REQUIRE(caught);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_disconnect_fully_disconnects) {
|
||||
std::variant<observable<>, std::array<char, 100>> pub = observable<>();
|
||||
observer<> sub = std::get<observable<>>(pub).observe([] {});
|
||||
sub.disconnect();
|
||||
auto x = std::array<char, 100>{};
|
||||
std::iota(x.begin(), x.end(), 'X');
|
||||
// Once upon a time, disconnect() still remembered the observable's address.
|
||||
// Simulate a the observable being freed and its memory reused for something
|
||||
// else by assigning garbage to the variant that holds its data
|
||||
pub = x;
|
||||
// Would have accessed the overwritten observable before the bug fix.
|
||||
sub.disconnect();
|
||||
}
|
||||
|
||||
@@ -92,6 +92,7 @@ public:
|
||||
if (_observable) {
|
||||
_observable->destroyed(this);
|
||||
}
|
||||
_observable = nullptr;
|
||||
}
|
||||
};
|
||||
friend class observer;
|
||||
|
||||
Reference in New Issue
Block a user