Commit bdd75627 authored by Dominik Charousset's avatar Dominik Charousset

Fix reference count of tuple decorators

parent a71505bb
...@@ -32,16 +32,16 @@ class concatenated_tuple : public message_data { ...@@ -32,16 +32,16 @@ class concatenated_tuple : public message_data {
public: public:
concatenated_tuple& operator=(const concatenated_tuple&) = delete; concatenated_tuple& operator=(const concatenated_tuple&) = delete;
using pointer = message_data::ptr; using message_data::cow_ptr;
using vector_type = std::vector<pointer>; using vector_type = std::vector<cow_ptr>;
static pointer make(std::initializer_list<pointer> xs); static cow_ptr make(std::initializer_list<cow_ptr> xs);
void* mutable_at(size_t pos) override; void* mutable_at(size_t pos) override;
size_t size() const override; size_t size() const override;
concatenated_tuple* copy() const override; cow_ptr copy() const override;
const void* at(size_t pos) const override; const void* at(size_t pos) const override;
......
...@@ -41,16 +41,16 @@ class decorated_tuple : public message_data { ...@@ -41,16 +41,16 @@ class decorated_tuple : public message_data {
using vector_type = std::vector<size_t>; using vector_type = std::vector<size_t>;
using pointer = message_data::ptr; using message_data::cow_ptr;
// creates a typed subtuple from `d` with mapping `v` // creates a typed subtuple from `d` with mapping `v`
static pointer make(pointer d, vector_type v); static cow_ptr make(cow_ptr d, vector_type v);
void* mutable_at(size_t pos) override; void* mutable_at(size_t pos) override;
size_t size() const override; size_t size() const override;
decorated_tuple* copy() const override; cow_ptr copy() const override;
const void* at(size_t pos) const override; const void* at(size_t pos) const override;
...@@ -63,7 +63,7 @@ class decorated_tuple : public message_data { ...@@ -63,7 +63,7 @@ class decorated_tuple : public message_data {
uint16_t type_nr_at(size_t pos) const override; uint16_t type_nr_at(size_t pos) const override;
inline const pointer& decorated() const { inline const cow_ptr& decorated() const {
return m_decorated; return m_decorated;
} }
...@@ -72,10 +72,10 @@ class decorated_tuple : public message_data { ...@@ -72,10 +72,10 @@ class decorated_tuple : public message_data {
} }
private: private:
decorated_tuple(pointer&&, vector_type&&); decorated_tuple(cow_ptr&&, vector_type&&);
decorated_tuple(const decorated_tuple&) = default; decorated_tuple(const decorated_tuple&) = default;
pointer m_decorated; cow_ptr m_decorated;
vector_type m_mapping; vector_type m_mapping;
uint32_t m_type_token; uint32_t m_type_token;
}; };
......
...@@ -162,6 +162,7 @@ class basic_memory_cache : public memory_cache { ...@@ -162,6 +162,7 @@ class basic_memory_cache : public memory_cache {
// allocate cache on-the-fly // allocate cache on-the-fly
if (!m_cache) { if (!m_cache) {
m_cache.reset(new storage, false); // starts with ref count of 1 m_cache.reset(new storage, false); // starts with ref count of 1
CAF_REQUIRE(m_cache->unique());
} }
auto res = m_cache->next(); auto res = m_cache->next();
if (m_cache->has_next()) { if (m_cache->has_next()) {
...@@ -170,7 +171,7 @@ class basic_memory_cache : public memory_cache { ...@@ -170,7 +171,7 @@ class basic_memory_cache : public memory_cache {
// we got the last element out of the cache; pass the reference to the // we got the last element out of the cache; pass the reference to the
// client to avoid pointless increase/decrease ops on the reference count // client to avoid pointless increase/decrease ops on the reference count
embedded_storage result; embedded_storage result;
result.first = std::move(m_cache); result.first.reset(m_cache.release(), false);
result.second = res; result.second = res;
return result; return result;
} }
......
...@@ -59,8 +59,6 @@ class message_data : public ref_counted { ...@@ -59,8 +59,6 @@ class message_data : public ref_counted {
virtual size_t size() const = 0; virtual size_t size() const = 0;
virtual message_data* copy() const = 0;
virtual const void* at(size_t pos) const = 0; virtual const void* at(size_t pos) const = 0;
// Tries to match element at position `pos` to given RTTI. // Tries to match element at position `pos` to given RTTI.
...@@ -77,15 +75,19 @@ class message_data : public ref_counted { ...@@ -77,15 +75,19 @@ class message_data : public ref_counted {
* nested types * * nested types *
****************************************************************************/ ****************************************************************************/
class ptr { class cow_ptr {
public: public:
ptr() = default; cow_ptr() = default;
ptr(ptr&&) = default; cow_ptr(cow_ptr&&) = default;
ptr(const ptr&) = default; cow_ptr(const cow_ptr&) = default;
ptr& operator=(ptr&&) = default; cow_ptr& operator=(cow_ptr&&) = default;
ptr& operator=(const ptr&) = default; cow_ptr& operator=(const cow_ptr&) = default;
inline ptr(intrusive_ptr<message_data> p) : m_ptr(std::move(p)) { inline cow_ptr(intrusive_ptr<message_data> p) : m_ptr(std::move(p)) {
// nop
}
inline cow_ptr(message_data* ptr, bool add_ref) : m_ptr(ptr, add_ref) {
// nop // nop
} }
...@@ -93,7 +95,7 @@ class message_data : public ref_counted { ...@@ -93,7 +95,7 @@ class message_data : public ref_counted {
* modifiers * * modifiers *
**************************************************************************/ **************************************************************************/
inline void swap(ptr& other) { inline void swap(cow_ptr& other) {
m_ptr.swap(other.m_ptr); m_ptr.swap(other.m_ptr);
} }
...@@ -140,6 +142,8 @@ class message_data : public ref_counted { ...@@ -140,6 +142,8 @@ class message_data : public ref_counted {
message_data* get_detached(); message_data* get_detached();
intrusive_ptr<message_data> m_ptr; intrusive_ptr<message_data> m_ptr;
}; };
virtual cow_ptr copy() const = 0;
}; };
} // namespace detail } // namespace detail
......
...@@ -98,8 +98,8 @@ class tuple_vals : public message_data { ...@@ -98,8 +98,8 @@ class tuple_vals : public message_data {
return sizeof...(Ts); return sizeof...(Ts);
} }
tuple_vals* copy() const override { message_data::cow_ptr copy() const override {
return new tuple_vals(*this); return message_data::cow_ptr(new tuple_vals(*this), false);
} }
const void* at(size_t pos) const override { const void* at(size_t pos) const override {
......
...@@ -309,7 +309,7 @@ class message { ...@@ -309,7 +309,7 @@ class message {
using raw_ptr = detail::message_data*; using raw_ptr = detail::message_data*;
using data_ptr = detail::message_data::ptr; using data_ptr = detail::message_data::cow_ptr;
explicit message(raw_ptr); explicit message(raw_ptr);
...@@ -462,7 +462,7 @@ make_message(V&& v, Vs&&... vs) { ...@@ -462,7 +462,7 @@ make_message(V&& v, Vs&&... vs) {
typename detail::strip_and_convert<Vs>::type typename detail::strip_and_convert<Vs>::type
>::type...>; >::type...>;
auto ptr = make_counted<storage>(std::forward<V>(v), std::forward<Vs>(vs)...); auto ptr = make_counted<storage>(std::forward<V>(v), std::forward<Vs>(vs)...);
return message{detail::message_data::ptr{std::move(ptr)}}; return message{detail::message_data::cow_ptr{std::move(ptr)}};
} }
/** /**
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include <QEvent> #include <QEvent>
#include <QApplication> #include <QApplication>
#include "caf/make_counted.hpp"
#include "caf/actor_companion.hpp" #include "caf/actor_companion.hpp"
#include "caf/message_handler.hpp" #include "caf/message_handler.hpp"
...@@ -55,7 +56,7 @@ class actor_widget : public Base { ...@@ -55,7 +56,7 @@ class actor_widget : public Base {
template <typename... Ts> template <typename... Ts>
actor_widget(Ts&&... args) : Base(std::forward<Ts>(args)...) { actor_widget(Ts&&... args) : Base(std::forward<Ts>(args)...) {
m_companion.reset(detail::memory::create<actor_companion>()); m_companion = make_counted<actor_companion>();
m_companion->on_enqueue([=](message_pointer ptr) { m_companion->on_enqueue([=](message_pointer ptr) {
qApp->postEvent(this, new event_type(std::move(ptr))); qApp->postEvent(this, new event_type(std::move(ptr)));
}); });
......
...@@ -39,8 +39,7 @@ void actor_companion::on_enqueue(enqueue_handler handler) { ...@@ -39,8 +39,7 @@ void actor_companion::on_enqueue(enqueue_handler handler) {
void actor_companion::enqueue(const actor_addr& sender, message_id mid, void actor_companion::enqueue(const actor_addr& sender, message_id mid,
message content, execution_unit*) { message content, execution_unit*) {
using detail::memory; using detail::memory;
message_pointer ptr{memory::create<mailbox_element>(sender, mid, auto ptr = mailbox_element::make(sender, mid, std::move(content));
std::move(content))};
shared_lock<lock_type> guard(m_lock); shared_lock<lock_type> guard(m_lock);
if (m_on_enqueue) { if (m_on_enqueue) {
m_on_enqueue(std::move(ptr)); m_on_enqueue(std::move(ptr));
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
namespace caf { namespace caf {
namespace detail { namespace detail {
auto concatenated_tuple::make(std::initializer_list<pointer> xs) -> pointer { auto concatenated_tuple::make(std::initializer_list<cow_ptr> xs) -> cow_ptr {
auto result = make_counted<concatenated_tuple>(); auto result = make_counted<concatenated_tuple>();
for (auto& x : xs) { for (auto& x : xs) {
if (x) { if (x) {
...@@ -41,7 +41,7 @@ auto concatenated_tuple::make(std::initializer_list<pointer> xs) -> pointer { ...@@ -41,7 +41,7 @@ auto concatenated_tuple::make(std::initializer_list<pointer> xs) -> pointer {
} }
} }
result->init(); result->init();
return pointer{std::move(result)}; return cow_ptr{std::move(result)};
} }
void* concatenated_tuple::mutable_at(size_t pos) { void* concatenated_tuple::mutable_at(size_t pos) {
...@@ -54,8 +54,8 @@ size_t concatenated_tuple::size() const { ...@@ -54,8 +54,8 @@ size_t concatenated_tuple::size() const {
return m_size; return m_size;
} }
concatenated_tuple* concatenated_tuple::copy() const { message_data::cow_ptr concatenated_tuple::copy() const {
return new concatenated_tuple(*this); return cow_ptr(new concatenated_tuple(*this), false);
} }
const void* concatenated_tuple::at(size_t pos) const { const void* concatenated_tuple::at(size_t pos) const {
...@@ -106,7 +106,7 @@ void concatenated_tuple::init() { ...@@ -106,7 +106,7 @@ void concatenated_tuple::init() {
m_type_token = add_to_type_token(m_type_token, m->type_nr_at(i)); m_type_token = add_to_type_token(m_type_token, m->type_nr_at(i));
} }
} }
auto acc_size = [](size_t tmp, const pointer& val) { auto acc_size = [](size_t tmp, const cow_ptr& val) {
return tmp + val->size(); return tmp + val->size();
}; };
m_size = std::accumulate(m_data.begin(), m_data.end(), size_t{0}, acc_size); m_size = std::accumulate(m_data.begin(), m_data.end(), size_t{0}, acc_size);
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
namespace caf { namespace caf {
namespace detail { namespace detail {
decorated_tuple::pointer decorated_tuple::make(pointer d, vector_type v) { decorated_tuple::cow_ptr decorated_tuple::make(cow_ptr d, vector_type v) {
auto ptr = dynamic_cast<const decorated_tuple*>(d.get()); auto ptr = dynamic_cast<const decorated_tuple*>(d.get());
if (ptr) { if (ptr) {
d = ptr->decorated(); d = ptr->decorated();
...@@ -31,7 +31,7 @@ decorated_tuple::pointer decorated_tuple::make(pointer d, vector_type v) { ...@@ -31,7 +31,7 @@ decorated_tuple::pointer decorated_tuple::make(pointer d, vector_type v) {
v[i] = pmap[v[i]]; v[i] = pmap[v[i]];
} }
} }
return pointer{new decorated_tuple(std::move(d), std::move(v))}; return cow_ptr{new decorated_tuple(std::move(d), std::move(v))};
} }
void* decorated_tuple::mutable_at(size_t pos) { void* decorated_tuple::mutable_at(size_t pos) {
...@@ -43,8 +43,8 @@ size_t decorated_tuple::size() const { ...@@ -43,8 +43,8 @@ size_t decorated_tuple::size() const {
return m_mapping.size(); return m_mapping.size();
} }
decorated_tuple* decorated_tuple::copy() const { message_data::cow_ptr decorated_tuple::copy() const {
return new decorated_tuple(*this); return cow_ptr(new decorated_tuple(*this), false);
} }
const void* decorated_tuple::at(size_t pos) const { const void* decorated_tuple::at(size_t pos) const {
...@@ -69,13 +69,13 @@ uint16_t decorated_tuple::type_nr_at(size_t pos) const { ...@@ -69,13 +69,13 @@ uint16_t decorated_tuple::type_nr_at(size_t pos) const {
return m_decorated->type_nr_at(m_mapping[pos]); return m_decorated->type_nr_at(m_mapping[pos]);
} }
decorated_tuple::decorated_tuple(pointer&& d, vector_type&& v) decorated_tuple::decorated_tuple(cow_ptr&& d, vector_type&& v)
: m_decorated(std::move(d)), : m_decorated(std::move(d)),
m_mapping(std::move(v)), m_mapping(std::move(v)),
m_type_token(0xFFFFFFFF) { m_type_token(0xFFFFFFFF) {
CAF_REQUIRE(m_mapping.empty() CAF_REQUIRE(m_mapping.empty()
|| *(std::max_element(m_mapping.begin(), m_mapping.end())) || *(std::max_element(m_mapping.begin(), m_mapping.end()))
< static_cast<const pointer&>(m_decorated)->size()); < static_cast<const cow_ptr&>(m_decorated)->size());
// calculate type token // calculate type token
for (size_t i = 0; i < m_mapping.size(); ++i) { for (size_t i = 0; i < m_mapping.size(); ++i) {
m_type_token <<= 6; m_type_token <<= 6;
......
...@@ -66,8 +66,8 @@ class message_builder::dynamic_msg_data : public detail::message_data { ...@@ -66,8 +66,8 @@ class message_builder::dynamic_msg_data : public detail::message_data {
return m_elements.size(); return m_elements.size();
} }
dynamic_msg_data* copy() const override { cow_ptr copy() const override {
return new dynamic_msg_data(*this); return cow_ptr(new dynamic_msg_data(*this), false);
} }
bool match_element(size_t pos, uint16_t typenr, bool match_element(size_t pos, uint16_t typenr,
...@@ -174,8 +174,8 @@ message_builder::dynamic_msg_data* message_builder::data() { ...@@ -174,8 +174,8 @@ message_builder::dynamic_msg_data* message_builder::data() {
// operations on m_data can cause race conditions if // operations on m_data can cause race conditions if
// someone else holds a reference to m_data // someone else holds a reference to m_data
if (!m_data->unique()) { if (!m_data->unique()) {
intrusive_ptr<ref_counted> tmp{std::move(m_data)}; auto tmp = static_cast<dynamic_msg_data*>(m_data.get())->copy();
m_data.reset(static_cast<dynamic_msg_data*>(tmp.get())->copy()); m_data.reset(tmp.release(), false);
} }
return static_cast<dynamic_msg_data*>(m_data.get()); return static_cast<dynamic_msg_data*>(m_data.get());
} }
......
...@@ -65,13 +65,12 @@ std::string message_data::tuple_type_names() const { ...@@ -65,13 +65,12 @@ std::string message_data::tuple_type_names() const {
return result; return result;
} }
message_data* message_data::ptr::get_detached() { message_data* message_data::cow_ptr::get_detached() {
auto p = m_ptr.get(); auto p = m_ptr.get();
if (!p->unique()) { if (!p->unique()) {
auto np = p->copy(); auto cptr = p->copy();
CAF_REQUIRE(np->unique()); m_ptr.swap(cptr.m_ptr);
m_ptr.reset(np, false); return m_ptr.get();
return np;
} }
return p; return p;
} }
......
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