Commit 59f5dba9 authored by Dominik Charousset's avatar Dominik Charousset

changed become/unbecome handling

parent 070eeb98
...@@ -85,6 +85,7 @@ class abstract_event_based_actor : public detail::abstract_scheduled_actor { ...@@ -85,6 +85,7 @@ class abstract_event_based_actor : public detail::abstract_scheduled_actor {
stack_element; stack_element;
std::vector<stack_element> m_behavior_stack; std::vector<stack_element> m_behavior_stack;
std::vector<stack_element> m_erased_stack_elements;
detail::receive_policy m_recv_policy; detail::receive_policy m_recv_policy;
// provoke compiler errors for usage of receive() and related functions // provoke compiler errors for usage of receive() and related functions
......
...@@ -79,6 +79,7 @@ resume_result abstract_event_based_actor::resume(util::fiber*) { ...@@ -79,6 +79,7 @@ resume_result abstract_event_based_actor::resume(util::fiber*) {
if (m_recv_policy.invoke(this, e, current_behavior())) { if (m_recv_policy.invoke(this, e, current_behavior())) {
// try to match cached message before receiving new ones // try to match cached message before receiving new ones
do { do {
m_erased_stack_elements.clear();
if (m_behavior_stack.empty()) { if (m_behavior_stack.empty()) {
done_cb(); done_cb();
return resume_result::actor_done; return resume_result::actor_done;
......
...@@ -33,7 +33,6 @@ ...@@ -33,7 +33,6 @@
namespace cppa { namespace cppa {
event_based_actor::event_based_actor() { event_based_actor::event_based_actor() {
m_behavior_stack.reserve(2);
} }
void event_based_actor::quit(std::uint32_t reason) { void event_based_actor::quit(std::uint32_t reason) {
...@@ -49,18 +48,13 @@ void event_based_actor::quit(std::uint32_t reason) { ...@@ -49,18 +48,13 @@ void event_based_actor::quit(std::uint32_t reason) {
void event_based_actor::do_become(behavior* bhvr, bool has_ownership) { void event_based_actor::do_become(behavior* bhvr, bool has_ownership) {
reset_timeout(); reset_timeout();
request_timeout(bhvr->timeout()); request_timeout(bhvr->timeout());
if (m_behavior_stack.empty() == false) {
m_erased_stack_elements.emplace_back(std::move(m_behavior_stack.back()));
m_behavior_stack.pop_back();
}
stack_element new_element{bhvr}; stack_element new_element{bhvr};
if (!has_ownership) new_element.get_deleter().disable(); if (!has_ownership) new_element.get_deleter().disable();
// keep always the latest element in the stack to prevent subtle errors,
// e.g., the addresses of all variables in a lambda expression calling
// become() suddenly are invalid if we would pop the behavior!
if (m_behavior_stack.size() < 2) {
m_behavior_stack.push_back(std::move(new_element)); m_behavior_stack.push_back(std::move(new_element));
}
else {
m_behavior_stack[0] = std::move(m_behavior_stack[1]);
m_behavior_stack[1] = std::move(new_element);
}
} }
} // namespace cppa } // namespace cppa
...@@ -33,7 +33,8 @@ ...@@ -33,7 +33,8 @@
namespace cppa { namespace cppa {
void stacked_event_based_actor::unbecome() { void stacked_event_based_actor::unbecome() {
if (!m_behavior_stack.empty()) { if (m_behavior_stack.empty() == false) {
m_erased_stack_elements.emplace_back(std::move(m_behavior_stack.back()));
m_behavior_stack.pop_back(); m_behavior_stack.pop_back();
} }
} }
......
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