Commit b5de3fdd authored by Dominik Charousset's avatar Dominik Charousset

store exit reasons of actors in registry

parent 43f75506
...@@ -48,14 +48,28 @@ class actor_registry { ...@@ -48,14 +48,28 @@ class actor_registry {
public: public:
/**
* @brief A registry entry consists of a pointer to the actor and an
* exit reason. An entry with a nullptr means the actor has finished
* execution for given reason.
*/
typedef std::pair<actor_ptr, std::uint32_t> value_type;
actor_registry(); actor_registry();
/**
* @brief Returns the {nullptr, invalid_exit_reason}.
*/
value_type get_entry(actor_id key) const;
// return nullptr if the actor wasn't put *or* finished execution // return nullptr if the actor wasn't put *or* finished execution
actor_ptr get(actor_id key) const; inline actor_ptr get(actor_id key) const {
return get_entry(key).first;
}
void put(actor_id key, const actor_ptr& value); void put(actor_id key, const actor_ptr& value);
void erase(actor_id key); void erase(actor_id key, std::uint32_t reason);
// gets the next free actor id // gets the next free actor id
actor_id next_id(); actor_id next_id();
...@@ -73,14 +87,16 @@ class actor_registry { ...@@ -73,14 +87,16 @@ class actor_registry {
private: private:
typedef std::map<actor_id, value_type> entries;
std::atomic<size_t> m_running; std::atomic<size_t> m_running;
std::atomic<std::uint32_t> m_ids; std::atomic<actor_id> m_ids;
std::mutex m_running_mtx; std::mutex m_running_mtx;
std::condition_variable m_running_cv; std::condition_variable m_running_cv;
mutable util::shared_spinlock m_instances_mtx; mutable util::shared_spinlock m_instances_mtx;
std::map<std::uint32_t, actor_ptr> m_instances; entries m_entries;
}; };
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <stdexcept> #include <stdexcept>
#include "cppa/attachable.hpp" #include "cppa/attachable.hpp"
#include "cppa/exit_reason.hpp"
#include "cppa/detail/actor_registry.hpp" #include "cppa/detail/actor_registry.hpp"
#include "cppa/util/shared_lock_guard.hpp" #include "cppa/util/shared_lock_guard.hpp"
#include "cppa/util/upgrade_lock_guard.hpp" #include "cppa/util/upgrade_lock_guard.hpp"
...@@ -50,51 +51,52 @@ namespace cppa { namespace detail { ...@@ -50,51 +51,52 @@ namespace cppa { namespace detail {
actor_registry::actor_registry() : m_running(0), m_ids(1) { actor_registry::actor_registry() : m_running(0), m_ids(1) {
} }
actor_ptr actor_registry::get(actor_id key) const { actor_registry::value_type actor_registry::get_entry(actor_id key) const {
shared_guard guard(m_instances_mtx); shared_guard guard(m_instances_mtx);
auto i = m_instances.find(key); auto i = m_entries.find(key);
if (i != m_instances.end()) { if (i != m_entries.end()) {
return i->second; return i->second;
} }
return nullptr; return {nullptr, exit_reason::not_exited};
} }
void actor_registry::put(actor_id key, const actor_ptr& value) { void actor_registry::put(actor_id key, const actor_ptr& value) {
bool add_attachable = false; bool add_attachable = false;
if (value != nullptr) { if (value != nullptr) {
shared_guard guard(m_instances_mtx); shared_guard guard(m_instances_mtx);
auto i = m_instances.find(key); auto i = m_entries.find(key);
if (i == m_instances.end()) { if (i == m_entries.end()) {
auto entry = std::make_pair(key,
value_type(value,
exit_reason::not_exited));
upgrade_guard uguard(guard); upgrade_guard uguard(guard);
m_instances.insert(std::make_pair(key, value)); add_attachable = m_entries.insert(entry).second;
add_attachable = true;
} }
} }
if (add_attachable) { if (add_attachable) {
struct eraser : attachable { struct eraser : attachable {
actor_id m_id; actor_id m_id;
actor_registry* m_singleton; actor_registry* m_registry;
eraser(actor_id id, actor_registry* s) : m_id(id), m_singleton(s) { eraser(actor_id id, actor_registry* s) : m_id(id), m_registry(s) { }
} void actor_exited(std::uint32_t reason) {
void actor_exited(std::uint32_t) { m_registry->erase(m_id, reason);
m_singleton->erase(m_id);
} }
bool matches(const token&) { bool matches(const token&) {
return false; return false;
} }
}; };
const_cast<actor_ptr&>(value)->attach(new eraser(value->id(), this)); value->attach(new eraser(key, this));
} }
} }
void actor_registry::erase(actor_id key) { void actor_registry::erase(actor_id key, std::uint32_t reason) {
exclusive_guard guard(m_instances_mtx); exclusive_guard guard(m_instances_mtx);
auto i = std::find_if(m_instances.begin(), m_instances.end(), auto i = m_entries.find(key);
[=](const std::pair<actor_id, actor_ptr>& p) { if (i != m_entries.end()) {
return p.first == key; auto& entry = i->second;
}); entry.first = nullptr;
if (i != m_instances.end()) entry.second = reason;
m_instances.erase(i); }
} }
std::uint32_t actor_registry::next_id() { std::uint32_t actor_registry::next_id() {
......
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