Commit 4c617725 authored by Dominik Charousset's avatar Dominik Charousset

fixed possible memory corruption after shutdown

this patch fixes a possible memory corruption when the middleman is accessed
via a `protocol` parent pointer after `shutdown` was called
parent 3914dc01
......@@ -48,7 +48,7 @@ namespace cppa { namespace network {
/**
* @brief Multiplexes asynchronous IO.
*/
class middleman {
class middleman : public ref_counted {
friend class detail::singleton_manager;
......
......@@ -39,6 +39,7 @@
#include "cppa/actor.hpp"
#include "cppa/ref_counted.hpp"
#include "cppa/primitive_variant.hpp"
#include "cppa/intrusive_fwd_ptr.hpp"
#include "cppa/network/acceptor.hpp"
......@@ -82,6 +83,14 @@ class protocol : public ref_counted {
void run_later(std::function<void()> fun);
struct ref_ftor {
void operator()(abstract_middleman*) const;
};
struct deref_ftor {
void operator()(abstract_middleman*) const;
};
protected:
// note: not thread-safe; call only in run_later functor!
......@@ -96,13 +105,13 @@ class protocol : public ref_counted {
// note: not thread-safe; call only in run_later functor!
void stop_writer(continuable_reader* what);
inline abstract_middleman* parent() { return m_parent; }
inline abstract_middleman* parent() { return m_parent.get(); }
inline const abstract_middleman* parent() const { return m_parent; }
inline const abstract_middleman* parent() const { return m_parent.get(); }
private:
abstract_middleman* m_parent;
intrusive_fwd_ptr<abstract_middleman,ref_ftor,deref_ftor> m_parent;
};
......
......@@ -83,7 +83,7 @@ class logging_impl : public logging {
void operator()() {
ostringstream fname;
fname << "libcppa_" << getpid() << "_" << time(0) << ".log";
fstream out(fname.str().c_str(), ios::out);
fstream out(fname.str().c_str(), ios::app);
unique_ptr<log_event> event;
for (;;) {
event.reset(m_queue.pop());
......
......@@ -432,7 +432,8 @@ class middleman_impl : public abstract_middleman {
atomic_thread_fence(memory_order_seq_cst);
uint8_t dummy = 0;
if (write(m_pipe_write, &dummy, sizeof(dummy)) != sizeof(dummy)) {
CPPA_CRITICAL("cannot write to pipe");
// already exited?
CPPA_LOG_WARNING("cannot write to pipe");
}
}
......@@ -446,6 +447,8 @@ class middleman_impl : public abstract_middleman {
detail::fd_util::nonblocking(m_pipe_read, true);
// start threads
m_thread = thread([this] { middleman_loop(this); });
// increase reference count for singleton manager
ref();
}
void destroy() {
......@@ -457,7 +460,9 @@ class middleman_impl : public abstract_middleman {
m_thread.join();
close(m_pipe_read);
close(m_pipe_write);
delete this;
// decrease reference count for singleton manager
deref();
//delete this;
}
private:
......
......@@ -34,9 +34,20 @@
namespace cppa { namespace network {
protocol::protocol(abstract_middleman* parent) : m_parent(parent) { }
void protocol::ref_ftor::operator()(abstract_middleman* ptr) const {
if (ptr) ptr->ref();
}
void protocol::deref_ftor::operator()(abstract_middleman* ptr) const {
if (ptr) ptr->deref();
}
protocol::protocol(abstract_middleman* parent) : m_parent(parent) {
CPPA_REQUIRE(parent != nullptr);
}
void protocol::run_later(std::function<void()> fun) {
CPPA_REQUIRE(m_parent != nullptr);
m_parent->run_later(std::move(fun));
}
......
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