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 { ...@@ -48,7 +48,7 @@ namespace cppa { namespace network {
/** /**
* @brief Multiplexes asynchronous IO. * @brief Multiplexes asynchronous IO.
*/ */
class middleman { class middleman : public ref_counted {
friend class detail::singleton_manager; friend class detail::singleton_manager;
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include "cppa/actor.hpp" #include "cppa/actor.hpp"
#include "cppa/ref_counted.hpp" #include "cppa/ref_counted.hpp"
#include "cppa/primitive_variant.hpp" #include "cppa/primitive_variant.hpp"
#include "cppa/intrusive_fwd_ptr.hpp"
#include "cppa/network/acceptor.hpp" #include "cppa/network/acceptor.hpp"
...@@ -82,6 +83,14 @@ class protocol : public ref_counted { ...@@ -82,6 +83,14 @@ class protocol : public ref_counted {
void run_later(std::function<void()> fun); void run_later(std::function<void()> fun);
struct ref_ftor {
void operator()(abstract_middleman*) const;
};
struct deref_ftor {
void operator()(abstract_middleman*) const;
};
protected: protected:
// note: not thread-safe; call only in run_later functor! // note: not thread-safe; call only in run_later functor!
...@@ -96,13 +105,13 @@ class protocol : public ref_counted { ...@@ -96,13 +105,13 @@ class protocol : public ref_counted {
// note: not thread-safe; call only in run_later functor! // note: not thread-safe; call only in run_later functor!
void stop_writer(continuable_reader* what); 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: 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 { ...@@ -83,7 +83,7 @@ class logging_impl : public logging {
void operator()() { void operator()() {
ostringstream fname; ostringstream fname;
fname << "libcppa_" << getpid() << "_" << time(0) << ".log"; 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; unique_ptr<log_event> event;
for (;;) { for (;;) {
event.reset(m_queue.pop()); event.reset(m_queue.pop());
......
...@@ -432,7 +432,8 @@ class middleman_impl : public abstract_middleman { ...@@ -432,7 +432,8 @@ class middleman_impl : public abstract_middleman {
atomic_thread_fence(memory_order_seq_cst); atomic_thread_fence(memory_order_seq_cst);
uint8_t dummy = 0; uint8_t dummy = 0;
if (write(m_pipe_write, &dummy, sizeof(dummy)) != sizeof(dummy)) { 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 { ...@@ -446,6 +447,8 @@ class middleman_impl : public abstract_middleman {
detail::fd_util::nonblocking(m_pipe_read, true); detail::fd_util::nonblocking(m_pipe_read, true);
// start threads // start threads
m_thread = thread([this] { middleman_loop(this); }); m_thread = thread([this] { middleman_loop(this); });
// increase reference count for singleton manager
ref();
} }
void destroy() { void destroy() {
...@@ -457,7 +460,9 @@ class middleman_impl : public abstract_middleman { ...@@ -457,7 +460,9 @@ class middleman_impl : public abstract_middleman {
m_thread.join(); m_thread.join();
close(m_pipe_read); close(m_pipe_read);
close(m_pipe_write); close(m_pipe_write);
delete this; // decrease reference count for singleton manager
deref();
//delete this;
} }
private: private:
......
...@@ -34,9 +34,20 @@ ...@@ -34,9 +34,20 @@
namespace cppa { namespace network { 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) { void protocol::run_later(std::function<void()> fun) {
CPPA_REQUIRE(m_parent != nullptr);
m_parent->run_later(std::move(fun)); 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