Commit 8a7b70c9 authored by Dominik Charousset's avatar Dominik Charousset

refactored ref_counted: prohibit destructor calls and enforce use of...

refactored ref_counted: prohibit destructor calls and enforce use of request_deletion member function
parent e1a21a76
......@@ -54,13 +54,15 @@ class channel : public ref_counted {
public:
virtual ~channel();
/**
* @brief Enqueues @p msg to the list of received messages.
*/
virtual void enqueue(actor* sender, any_tuple msg) = 0;
protected:
virtual ~channel();
private:
// channel is a sealed class and the only
......
......@@ -84,9 +84,7 @@ class intrusive_ptr : util::comparable<intrusive_ptr<T> >,
set_ptr(from.convert());
}
~intrusive_ptr() {
if (m_ptr && !m_ptr->deref()) delete m_ptr;
}
~intrusive_ptr() { if (m_ptr) m_ptr->deref(); }
inline void swap(intrusive_ptr& other) {
std::swap(m_ptr, other.m_ptr);
......@@ -110,7 +108,7 @@ class intrusive_ptr : util::comparable<intrusive_ptr<T> >,
}
void reset(pointer new_value = nullptr) {
if (m_ptr && !m_ptr->deref()) delete m_ptr;
if (m_ptr) m_ptr->deref();
set_ptr(new_value);
}
......
......@@ -56,20 +56,27 @@ class ref_counted {
inline void ref() { ++m_rc; }
/**
* @brief Decreases reference cound by one.
* @returns @p true if there are still references to this object
* (reference count > 0); otherwise @p false.
* @brief Decreases reference count by one and calls
* @p request_deletion when it drops to zero.
*/
inline bool deref() { return --m_rc > 0; }
inline void deref() { if (--m_rc == 0) request_deletion(); }
/**
* @brief Queries if there is exactly one reference.
* @returns @p true if reference count is one; otherwise @p false.
* @brief Queries whether there is exactly one reference.
*/
inline bool unique() { return m_rc == 1; }
protected:
virtual ~ref_counted();
/**
* @brief Default implementations calls <tt>delete this</tt>, but can
* be overriden in case deletion depends on more than the
* reference count alone.
*/
virtual void request_deletion();
private:
std::atomic<size_t> m_rc;
......
......@@ -35,4 +35,6 @@ namespace cppa {
ref_counted::~ref_counted() { }
void ref_counted::request_deletion() { delete this; }
} // namespace cppa
......@@ -115,7 +115,7 @@ void self_type::cleanup_fun(cppa::local_actor* what) {
// make sure "unspawned" actors quit properly
ptr->cleanup(cppa::exit_reason::normal);
}
if (what->deref() == false) delete what;
what->deref();
}
}
......
......@@ -107,7 +107,7 @@ void singleton_manager::shutdown() {
delete s_group_manager.load();
s_group_manager = nullptr;
auto et = s_empty_tuple.load();
if (et && !et->deref()) delete et;
if (et) et->deref();
s_empty_tuple = nullptr;
delete s_uniform_type_info_map.load();
s_uniform_type_info_map = nullptr;
......
......@@ -138,7 +138,7 @@ struct thread_pool_scheduler::worker {
case resume_result::actor_done: {
auto pending = fetch_pending();
bool hidden = job->is_hidden();
if (!job->deref()) delete job;
job->deref();
std::atomic_thread_fence(std::memory_order_seq_cst);
if (!hidden) dec_actor_count();
job = pending;
......@@ -189,7 +189,7 @@ void thread_pool_scheduler::stop() {
while (ptr != nullptr) {
if (ptr != &m_dummy) {
bool hidden = ptr->is_hidden();
if (!ptr->deref()) delete ptr;
ptr->deref();
std::atomic_thread_fence(std::memory_order_seq_cst);
if (!hidden) dec_actor_count();
}
......
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