void sequencer::enqueue(mailbox_element_ptr what, execution_unit* context) { auto down_msg_handler = [&](down_msg& dm) { // quit if either `f` or `g` are no longer available cleanup(std::move(dm.reason), context); }; if (handle_system_message(*what, context, false, down_msg_handler)) return; strong_actor_ptr f; strong_actor_ptr g; error err; shared_critical_section([&] { f = f_; g = g_; err = fail_state_; }); if (!f) { // f and g are invalid only after the sequencer terminated bounce(what, err); return; } // process and forward the non-system message; // store `f` as the next stage in the forwarding chain what->stages.push_back(std::move(f)); // forward modified message to `g` g->enqueue(std::move(what), context); }
bool handle_system_message(mailbox_element& x, execution_unit* context, bool trap_exit, F& down_msg_handler) { auto& content = x.content(); if (content.type_token() == make_type_token<down_msg>()) { if (content.shared()) { auto vptr = content.copy(0); down_msg_handler(vptr->get_mutable_as<down_msg>()); } else { down_msg_handler(content.get_mutable_as<down_msg>(0)); } return true; } return handle_system_message(x, context, trap_exit); }