sml
sml copied to clipboard
queue_event default move assignment operator could cause improper destruction
We've uncovered an issue when deferring events that hold shared pointers. The issue manifests when the event is on the back end of a defer queue deque and is erased. It turns out that the deque will move events on the queue backwards, and with the default move assignment operator, the move/dtor on the underlying data is not called properly.
The code below triggers the issue. The program prints
- 2
- 1
#include <queue>
#include <memory>
#include <boost/sml.hpp>
namespace sml = boost::sml;
struct e1 {
std::shared_ptr<int> p;
};
struct e2 {};
struct e3 {};
struct table {
auto operator()() noexcept {
using namespace sml;
// clang-format off
return make_transition_table(
*"s1"_s + event<e1> / defer
, "s1"_s + event<e2> / defer
, "s1"_s + event<e3> = "s2"_s
, "s2"_s + event<e1> / [](auto const& ev) { std::cout << *ev.p << ": " << ev.p.use_count() << std::endl; }
, "s2"_s + event<e2> / defer
);
// clang-format on
}
};
int main() {
sml::sm<table, sml::defer_queue<std::deque>> sm;
auto e1val = std::make_shared<int>(1);
auto e2val = std::make_shared<int>(2);
sm.process_event(e2{});
sm.process_event(e2{});
sm.process_event(e2{});
sm.process_event(e2{});
sm.process_event(e2{});
sm.process_event(e2{});
sm.process_event(e2{});
sm.process_event(e1{ e1val });
sm.process_event(e1{ e2val });
sm.process_event(e3{});
}
Can this be closed, because https://github.com/boost-experimental/sml/pull/280 has been merged ?