Commit ee068c64 authored by Dominik Charousset's avatar Dominik Charousset

Fix memory leak in the message builder

parent 30ce7372
......@@ -17,6 +17,10 @@ namespace caf::detail {
/// later.
class CAF_CORE_EXPORT message_builder_element {
public:
message_builder_element() = default;
message_builder_element(const message_builder_element&) = delete;
message_builder_element& operator=(const message_builder_element&) = delete;
virtual ~message_builder_element();
/// Uses placement new to create a copy of the wrapped value at given memory
......@@ -34,10 +38,24 @@ public:
template <class T>
class message_builder_element_impl : public message_builder_element {
public:
message_builder_element_impl(T value) : value_(std::move(value)) {
template <class Value>
explicit message_builder_element_impl(Value&& value)
: value_(std::forward<Value>(value)) {
// nop
}
message_builder_element_impl() = delete;
message_builder_element_impl(message_builder_element_impl&&) = delete;
message_builder_element_impl(const message_builder_element_impl&) = delete;
message_builder_element_impl& operator=(message_builder_element_impl&&)
= delete;
message_builder_element_impl& operator=(const message_builder_element_impl&)
= delete;
byte* copy_init(byte* storage) const override {
new (storage) T(value_);
return storage + padded_size_v<T>;
......@@ -54,10 +72,4 @@ private:
using message_builder_element_ptr = std::unique_ptr<message_builder_element>;
template <class T>
auto make_message_builder_element(T&& x) {
using impl = message_builder_element_impl<std::decay_t<T>>;
return message_builder_element_ptr{new impl(std::forward<T>(x))};
}
} // namespace caf::detail
......@@ -45,12 +45,12 @@ public:
/// Adds `x` to the elements of the buffer.
template <class T>
message_builder& append(T&& x) {
using namespace detail;
using value_type = strip_and_convert_t<T>;
static_assert(sendable<value_type>);
storage_size_ += padded_size_v<value_type>;
using value_type = detail::strip_and_convert_t<T>;
static_assert(detail::sendable<value_type>);
using wrapper_type = detail::message_builder_element_impl<value_type>;
storage_size_ += detail::padded_size_v<value_type>;
types_.push_back(type_id_v<value_type>);
elements_.emplace_back(make_message_builder_element(std::forward<T>(x)));
elements_.emplace_back(std::make_unique<wrapper_type>(std::forward<T>(x)));
return *this;
}
......
......@@ -33,11 +33,13 @@ message to_message_impl(size_t storage_size, TypeListBuilder& types,
raw_ptr = new (vptr) message_data(types.copy_to_list());
intrusive_cow_ptr<message_data> ptr{raw_ptr, false};
auto storage = raw_ptr->storage();
for (auto& element : elements)
for (auto& element : elements) {
if constexpr (Policy == move_msg)
storage = element->move_init(storage);
else
storage = element->copy_init(storage);
raw_ptr->inc_constructed_elements();
}
return message{std::move(ptr)};
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment