Commit 31699f7f authored by Dominik Charousset's avatar Dominik Charousset

fixed several issues related to message priorities

this patch fixes several bugs that are related to the recently added
support for priorities; it also refactors the remote actors unit test
and improves logging
parent 7bf68b2b
...@@ -72,7 +72,7 @@ endif () ...@@ -72,7 +72,7 @@ endif ()
# set build type (evaluate ENABLE_DEBUG flag) # set build type (evaluate ENABLE_DEBUG flag)
if (ENABLE_DEBUG) if (ENABLE_DEBUG)
set(CMAKE_BUILD_TYPE Debug) set(CMAKE_BUILD_TYPE Debug)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DCPPA_ENABLE_DEBUG") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DCPPA_DEBUG_MODE")
endif (ENABLE_DEBUG) endif (ENABLE_DEBUG)
if (CPPA_LOG_LEVEL) if (CPPA_LOG_LEVEL)
......
...@@ -74,8 +74,6 @@ class actor : public channel { ...@@ -74,8 +74,6 @@ class actor : public channel {
public: public:
~actor();
/** /**
* @brief Attaches @p ptr to this actor. * @brief Attaches @p ptr to this actor.
* *
......
...@@ -55,7 +55,7 @@ ...@@ -55,7 +55,7 @@
#include <cstdio> #include <cstdio>
#include <cstdlib> #include <cstdlib>
#ifdef CPPA_ENABLE_DEBUG #ifdef CPPA_DEBUG_MODE
#include <execinfo.h> #include <execinfo.h>
#define CPPA_REQUIRE__(stmt, file, line) \ #define CPPA_REQUIRE__(stmt, file, line) \
...@@ -70,9 +70,9 @@ ...@@ -70,9 +70,9 @@
if ((stmt) == false) { \ if ((stmt) == false) { \
CPPA_REQUIRE__(#stmt, __FILE__, __LINE__); \ CPPA_REQUIRE__(#stmt, __FILE__, __LINE__); \
}((void) 0) }((void) 0)
#else // CPPA_ENABLE_DEBUG #else // CPPA_DEBUG_MODE
#define CPPA_REQUIRE(unused) ((void) 0) #define CPPA_REQUIRE(unused) ((void) 0)
#endif // CPPA_ENABLE_DEBUG #endif // CPPA_DEBUG_MODE
#define CPPA_CRITICAL__(error, file, line) { \ #define CPPA_CRITICAL__(error, file, line) { \
printf("%s:%u: critical error: '%s'\n", file, line, error); \ printf("%s:%u: critical error: '%s'\n", file, line, error); \
......
...@@ -38,7 +38,6 @@ ...@@ -38,7 +38,6 @@
#include "cppa/stacked.hpp" #include "cppa/stacked.hpp"
#include "cppa/scheduled_actor.hpp" #include "cppa/scheduled_actor.hpp"
#include "cppa/detail/receive_policy.hpp" #include "cppa/detail/receive_policy.hpp"
#include "cppa/detail/behavior_stack.hpp" #include "cppa/detail/behavior_stack.hpp"
#include "cppa/detail/yield_interface.hpp" #include "cppa/detail/yield_interface.hpp"
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include <tuple> #include <tuple>
#include <chrono> #include <chrono>
#include <cstdint> #include <cstdint>
#include <cstring>
#include <functional> #include <functional>
#include <type_traits> #include <type_traits>
...@@ -450,7 +451,7 @@ operator<<(const intrusive_ptr<C>& whom, any_tuple what) { ...@@ -450,7 +451,7 @@ operator<<(const intrusive_ptr<C>& whom, any_tuple what) {
} }
inline const self_type& operator<<(const self_type& s, any_tuple what) { inline const self_type& operator<<(const self_type& s, any_tuple what) {
send_tuple(s, std::move(what)); send_tuple(s.get(), std::move(what));
return s; return s;
} }
...@@ -458,17 +459,9 @@ inline const self_type& operator<<(const self_type& s, any_tuple what) { ...@@ -458,17 +459,9 @@ inline const self_type& operator<<(const self_type& s, any_tuple what) {
* @} * @}
*/ */
/* inline actor_ptr eval_sopts(spawn_options opts, local_actor_ptr ptr) {
// matches "send(this, ...)" and "send(self, ...)" CPPA_LOGF_INFO("spawned new local actor with ID " << ptr->id()
inline void send_tuple(channel* whom, any_tuple what) { << " of type " << detail::demangle(typeid(*ptr)));
detail::send_impl(whom, std::move(what));
}
template<typename... Ts>
inline void send(channel* whom, Ts&&... args) {
detail::send_tpl_impl(whom, std::forward<Ts>(args)...);
}
*/
inline actor_ptr eval_sopts(spawn_options opts, actor_ptr ptr) {
if (has_monitor_flag(opts)) self->monitor(ptr); if (has_monitor_flag(opts)) self->monitor(ptr);
if (has_link_flag(opts)) self->link_to(ptr); if (has_link_flag(opts)) self->link_to(ptr);
return std::move(ptr); return std::move(ptr);
...@@ -548,9 +541,9 @@ actor_ptr spawn_in_group(const group_ptr& grp, Ts&&... args) { ...@@ -548,9 +541,9 @@ actor_ptr spawn_in_group(const group_ptr& grp, Ts&&... args) {
*/ */
template<class Impl, spawn_options Options = no_spawn_options, typename... Ts> template<class Impl, spawn_options Options = no_spawn_options, typename... Ts>
actor_ptr spawn_in_group(const group_ptr& grp, Ts&&... args) { actor_ptr spawn_in_group(const group_ptr& grp, Ts&&... args) {
auto rawptr = detail::memory::create<Impl>(std::forward<Ts>(args)...); auto ptr = make_counted<Impl>(std::forward<Ts>(args)...);
rawptr->join(grp); ptr->join(grp);
return eval_sopts(Options, get_scheduler()->exec(Options, rawptr)); return eval_sopts(Options, get_scheduler()->exec(Options, ptr));
} }
/** @} */ /** @} */
......
...@@ -107,7 +107,7 @@ class decorated_tuple : public abstract_tuple { ...@@ -107,7 +107,7 @@ class decorated_tuple : public abstract_tuple {
decorated_tuple(cow_pointer_type d, const vector_type& v) decorated_tuple(cow_pointer_type d, const vector_type& v)
: super(false) : super(false)
, m_decorated(std::move(d)), m_mapping(v) { , m_decorated(std::move(d)), m_mapping(v) {
# ifdef CPPA_ENABLE_DEBUG # ifdef CPPA_DEBUG_MODE
const cow_pointer_type& ptr = m_decorated; // prevent detaching const cow_pointer_type& ptr = m_decorated; // prevent detaching
# endif # endif
CPPA_REQUIRE(ptr->size() >= sizeof...(Ts)); CPPA_REQUIRE(ptr->size() >= sizeof...(Ts));
...@@ -117,7 +117,7 @@ class decorated_tuple : public abstract_tuple { ...@@ -117,7 +117,7 @@ class decorated_tuple : public abstract_tuple {
decorated_tuple(cow_pointer_type d, size_t offset) decorated_tuple(cow_pointer_type d, size_t offset)
: super(false), m_decorated(std::move(d)) { : super(false), m_decorated(std::move(d)) {
# ifdef CPPA_ENABLE_DEBUG # ifdef CPPA_DEBUG_MODE
const cow_pointer_type& ptr = m_decorated; // prevent detaching const cow_pointer_type& ptr = m_decorated; // prevent detaching
# endif # endif
CPPA_REQUIRE((ptr->size() - offset) >= sizeof...(Ts)); CPPA_REQUIRE((ptr->size() - offset) >= sizeof...(Ts));
......
...@@ -48,13 +48,12 @@ struct sync_request_bouncer { ...@@ -48,13 +48,12 @@ struct sync_request_bouncer {
inline void operator()(const actor_ptr& sender, const message_id& mid) const { inline void operator()(const actor_ptr& sender, const message_id& mid) const {
CPPA_REQUIRE(rsn != exit_reason::not_exited); CPPA_REQUIRE(rsn != exit_reason::not_exited);
if (mid.is_request() && sender != nullptr) { if (mid.is_request() && sender != nullptr) {
actor_ptr nobody; sender->enqueue({nullptr, sender, mid.response_id()},
sender->enqueue({nobody, sender, mid.response_id()},
make_any_tuple(atom("EXITED"), rsn)); make_any_tuple(atom("EXITED"), rsn));
} }
} }
inline void operator()(const mailbox_element& e) const { inline void operator()(const mailbox_element& e) const {
(*this)(e.sender.get(), e.mid); (*this)(e.sender, e.mid);
} }
}; };
......
...@@ -329,7 +329,7 @@ struct tdata<Head, Tail...> : tdata<Tail...> { ...@@ -329,7 +329,7 @@ struct tdata<Head, Tail...> : tdata<Tail...> {
} }
inline void* mutable_at(size_t p) { inline void* mutable_at(size_t p) {
# ifdef CPPA_ENABLE_DEBUG # ifdef CPPA_DEBUG_MODE
if (p == 0) { if (p == 0) {
if (std::is_same<decltype(ptr_to(head)), const void*>::value) { if (std::is_same<decltype(ptr_to(head)), const void*>::value) {
throw std::logic_error{"mutable_at with const head"}; throw std::logic_error{"mutable_at with const head"};
......
...@@ -61,9 +61,9 @@ class thread_pool_scheduler : public scheduler { ...@@ -61,9 +61,9 @@ class thread_pool_scheduler : public scheduler {
void enqueue(scheduled_actor* what); void enqueue(scheduled_actor* what);
actor_ptr exec(spawn_options opts, scheduled_actor_ptr ptr); virtual local_actor_ptr exec(spawn_options opts, scheduled_actor_ptr ptr) override;
actor_ptr exec(spawn_options opts, init_callback init_cb, void_function f); virtual local_actor_ptr exec(spawn_options opts, init_callback init_cb, void_function f) override;
private: private:
......
...@@ -96,6 +96,8 @@ class local_actor : public extend<actor>::with<memory_cached> { ...@@ -96,6 +96,8 @@ class local_actor : public extend<actor>::with<memory_cached> {
public: public:
~local_actor();
/** /**
* @brief Causes this actor to subscribe to the group @p what. * @brief Causes this actor to subscribe to the group @p what.
* *
...@@ -267,14 +269,6 @@ class local_actor : public extend<actor>::with<memory_cached> { ...@@ -267,14 +269,6 @@ class local_actor : public extend<actor>::with<memory_cached> {
inline void dequeue_response(behavior&&, message_id); inline void dequeue_response(behavior&&, message_id);
/*
template<bool Discard, typename... Ts>
void become(behavior_policy<Discard>, Ts&&... args);
template<typename T, typename... Ts>
void become(T arg, Ts&&... args);
*/
inline void do_unbecome(); inline void do_unbecome();
local_actor(bool is_scheduled = false); local_actor(bool is_scheduled = false);
...@@ -312,12 +306,19 @@ class local_actor : public extend<actor>::with<memory_cached> { ...@@ -312,12 +306,19 @@ class local_actor : public extend<actor>::with<memory_cached> {
inline void do_become(const behavior& bhvr, bool discard_old); inline void do_become(const behavior& bhvr, bool discard_old);
const char* debug_name() const;
void debug_name(std::string str);
protected: protected:
inline void remove_handler(message_id id); inline void remove_handler(message_id id);
void cleanup(std::uint32_t reason); void cleanup(std::uint32_t reason);
// used *only* when compiled in debug mode
union { std::string m_debug_name; };
// true if this actor uses the chained_send optimization // true if this actor uses the chained_send optimization
bool m_chaining; bool m_chaining;
...@@ -403,18 +404,6 @@ inline actor_ptr& local_actor::last_sender() { ...@@ -403,18 +404,6 @@ inline actor_ptr& local_actor::last_sender() {
return m_current_node->sender; return m_current_node->sender;
} }
/*
template<bool Discard, typename... Ts>
inline void local_actor::become(behavior_policy<Discard>, Ts&&... args) {
do_become(match_expr_convert(std::forward<Ts>(args)...), Discard);
}
template<typename T, typename... Ts>
inline void local_actor::become(T arg, Ts&&... args) {
do_become(match_expr_convert(arg, std::forward<Ts>(args)...), true);
}
*/
inline void local_actor::do_unbecome() { inline void local_actor::do_unbecome() {
m_bhvr_stack.pop_async_back(); m_bhvr_stack.pop_async_back();
} }
......
...@@ -114,12 +114,8 @@ inline actor_ptr fwd_aptr(const self_type& s) { ...@@ -114,12 +114,8 @@ inline actor_ptr fwd_aptr(const self_type& s) {
return s.unchecked(); return s.unchecked();
} }
inline actor_ptr fwd_aptr(actor* ptr) { inline actor_ptr fwd_aptr(actor_ptr ptr) {
return ptr; return std::move(ptr);
}
inline actor_ptr fwd_aptr(const actor_ptr& ptr) {
return ptr;
} }
struct oss_wr { struct oss_wr {
...@@ -165,6 +161,13 @@ oss_wr operator<<(oss_wr&& lhs, T rhs) { ...@@ -165,6 +161,13 @@ oss_wr operator<<(oss_wr&& lhs, T rhs) {
#define CPPA_DEBUG 3 #define CPPA_DEBUG 3
#define CPPA_TRACE 4 #define CPPA_TRACE 4
#ifdef CPPA_DEBUG_MODE
# define CPPA_SET_DEBUG_NAME(strstr) \
self->debug_name((::cppa::oss_wr{} << strstr).str());
#else
# define CPPA_SET_DEBUG_NAME(unused)
#endif
#define CPPA_LVL_NAME0() "ERROR" #define CPPA_LVL_NAME0() "ERROR"
#define CPPA_LVL_NAME1() "WARN " #define CPPA_LVL_NAME1() "WARN "
#define CPPA_LVL_NAME2() "INFO " #define CPPA_LVL_NAME2() "INFO "
...@@ -172,9 +175,9 @@ oss_wr operator<<(oss_wr&& lhs, T rhs) { ...@@ -172,9 +175,9 @@ oss_wr operator<<(oss_wr&& lhs, T rhs) {
#define CPPA_LVL_NAME4() "TRACE" #define CPPA_LVL_NAME4() "TRACE"
#ifndef CPPA_LOG_LEVEL #ifndef CPPA_LOG_LEVEL
# define CPPA_LOG_IMPL(lvlname, classname, funname, unused, message) {\ # define CPPA_LOG_IMPL(lvlname, classname, funname, unused, message) { \
std::cerr << "[" << lvlname << "] " << classname << "::" << funname << ": " \ std::cerr << "[" << lvlname << "] " << classname << "::" \
<< message << "\nStack trace:\n"; \ << funname << ": " << message << "\nStack trace:\n"; \
void *array[10]; \ void *array[10]; \
size_t size = backtrace(array, 10); \ size_t size = backtrace(array, 10); \
backtrace_symbols_fd(array, size, 2); \ backtrace_symbols_fd(array, size, 2); \
...@@ -287,7 +290,7 @@ oss_wr operator<<(oss_wr&& lhs, T rhs) { ...@@ -287,7 +290,7 @@ oss_wr operator<<(oss_wr&& lhs, T rhs) {
/****************************************************************************** /******************************************************************************
* backward compatibility for version <= 0.6 * * convenience macros *
******************************************************************************/ ******************************************************************************/
#define CPPA_LOG_ERROR(msg) CPPA_LOGMF(CPPA_ERROR, ::cppa::self, msg) #define CPPA_LOG_ERROR(msg) CPPA_LOGMF(CPPA_ERROR, ::cppa::self, msg)
......
...@@ -165,18 +165,18 @@ class scheduler { ...@@ -165,18 +165,18 @@ class scheduler {
/** /**
* @brief Executes @p ptr in this scheduler. * @brief Executes @p ptr in this scheduler.
*/ */
virtual actor_ptr exec(spawn_options opts, scheduled_actor_ptr ptr) = 0; virtual local_actor_ptr exec(spawn_options opts, scheduled_actor_ptr ptr) = 0;
/** /**
* @brief Creates a new actor from @p actor_behavior and executes it * @brief Creates a new actor from @p actor_behavior and executes it
* in this scheduler. * in this scheduler.
*/ */
virtual actor_ptr exec(spawn_options opts, virtual local_actor_ptr exec(spawn_options opts,
init_callback init_cb, init_callback init_cb,
void_function actor_behavior) = 0; void_function actor_behavior) = 0;
template<typename F, typename T, typename... Ts> template<typename F, typename T, typename... Ts>
actor_ptr exec(spawn_options opts, init_callback cb, local_actor_ptr exec(spawn_options opts, init_callback cb,
F f, T&& a0, Ts&&... as) { F f, T&& a0, Ts&&... as) {
return this->exec(opts, cb, std::bind(f, detail::fwd<T>(a0), return this->exec(opts, cb, std::bind(f, detail::fwd<T>(a0),
detail::fwd<Ts>(as)...)); detail::fwd<Ts>(as)...));
......
...@@ -46,19 +46,33 @@ namespace cppa { ...@@ -46,19 +46,33 @@ namespace cppa {
* @{ * @{
*/ */
struct destination_header {
channel_ptr receiver;
message_priority priority;
inline destination_header(const self_type& s)
: receiver(s), priority(message_priority::normal) { }
template<typename T>
inline destination_header(T dest)
: receiver(std::move(dest)), priority(message_priority::normal) { }
inline destination_header(channel_ptr dest, message_priority prio)
: receiver(std::move(dest)), priority(prio) { }
inline destination_header(destination_header&& hdr)
: receiver(std::move(hdr.receiver)), priority(hdr.priority) { }
};
/** /**
* @brief Sends @p what to the receiver specified in @p hdr. * @brief Sends @p what to the receiver specified in @p hdr.
*/ */
inline void send_tuple(const message_header& hdr, any_tuple what) { inline void send_tuple(destination_header hdr, any_tuple what) {
if (hdr.receiver == nullptr) return; if (hdr.receiver == nullptr) return;
local_actor* sptr = self.unchecked(); message_header fhdr{self, std::move(hdr.receiver), hdr.priority};
if (sptr && sptr->chaining_enabled()) { if (self->chaining_enabled()) {
if (hdr.receiver->chained_enqueue(hdr, std::move(what))) { if (fhdr.receiver->chained_enqueue(fhdr, std::move(what))) {
// only actors implement chained_enqueue to return true // only actors implement chained_enqueue to return true
sptr->chained_actor(static_cast<actor*>(hdr.receiver.get())); self->chained_actor(fhdr.receiver.downcast<actor>());
} }
} }
else hdr.receiver->enqueue(hdr, std::move(what)); else fhdr.deliver(std::move(what));
} }
/** /**
...@@ -66,16 +80,17 @@ inline void send_tuple(const message_header& hdr, any_tuple what) { ...@@ -66,16 +80,17 @@ inline void send_tuple(const message_header& hdr, any_tuple what) {
* @pre <tt>sizeof...(Ts) > 0</tt> * @pre <tt>sizeof...(Ts) > 0</tt>
*/ */
template<typename... Ts> template<typename... Ts>
inline void send(const message_header& hdr, Ts&&... what) { inline void send(destination_header hdr, Ts&&... what) {
static_assert(sizeof...(Ts) > 0, "no message to send"); static_assert(sizeof...(Ts) > 0, "no message to send");
send_tuple(hdr, make_any_tuple(std::forward<Ts>(what)...)); send_tuple(std::move(hdr), make_any_tuple(std::forward<Ts>(what)...));
} }
/** /**
* @brief Sends @p what to @p whom, but sets the sender information to @p from. * @brief Sends @p what to @p whom, but sets the sender information to @p from.
*/ */
inline void send_tuple_as(actor_ptr from, channel_ptr whom, any_tuple what) { inline void send_tuple_as(actor_ptr from, channel_ptr whom, any_tuple what) {
send_tuple({std::move(from), std::move(whom)}, std::move(what)); message_header hdr{std::move(from), std::move(whom)};
hdr.deliver(std::move(what));
} }
/** /**
...@@ -88,7 +103,7 @@ inline void send_tuple_as(actor_ptr from, channel_ptr whom, any_tuple what) { ...@@ -88,7 +103,7 @@ inline void send_tuple_as(actor_ptr from, channel_ptr whom, any_tuple what) {
*/ */
template<typename... Ts> template<typename... Ts>
inline void send_as(actor_ptr from, channel_ptr whom, Ts&&... what) { inline void send_as(actor_ptr from, channel_ptr whom, Ts&&... what) {
send_tuple({std::move(from), std::move(whom)}, send_tuple_as(std::move(from), std::move(whom),
make_any_tuple(std::forward<Ts>(what)...)); make_any_tuple(std::forward<Ts>(what)...));
} }
...@@ -104,7 +119,13 @@ inline void send_as(actor_ptr from, channel_ptr whom, Ts&&... what) { ...@@ -104,7 +119,13 @@ inline void send_as(actor_ptr from, channel_ptr whom, Ts&&... what) {
inline message_future sync_send_tuple(actor_ptr whom, any_tuple what) { inline message_future sync_send_tuple(actor_ptr whom, any_tuple what) {
if (!whom) throw std::invalid_argument("whom == nullptr"); if (!whom) throw std::invalid_argument("whom == nullptr");
auto req = self->new_request_id(); auto req = self->new_request_id();
send_tuple({std::move(whom), req}, std::move(what)); message_header hdr{self, std::move(whom), req};
if (self->chaining_enabled()) {
if (hdr.receiver->chained_enqueue(hdr, std::move(what))) {
self->chained_actor(hdr.receiver.downcast<actor>());
}
}
else hdr.deliver(std::move(what));
return req.response_id(); return req.response_id();
} }
......
...@@ -51,7 +51,7 @@ enum class spawn_options : int { ...@@ -51,7 +51,7 @@ enum class spawn_options : int {
detach_flag = 0x04, detach_flag = 0x04,
hide_flag = 0x08, hide_flag = 0x08,
blocking_api_flag = 0x10, blocking_api_flag = 0x10,
priority_aware_flag = 0x24 // priority-aware actors are also detached priority_aware_flag = 0x20
}; };
#endif #endif
...@@ -59,6 +59,15 @@ enum class spawn_options : int { ...@@ -59,6 +59,15 @@ enum class spawn_options : int {
namespace { namespace {
#endif #endif
/**
* @brief Concatenates two {@link spawn_options}.
* @relates spawn_options
*/
constexpr spawn_options operator+(const spawn_options& lhs,
const spawn_options& rhs) {
return static_cast<spawn_options>(static_cast<int>(lhs) | static_cast<int>(rhs));
}
/** /**
* @brief Denotes default settings. * @brief Denotes default settings.
*/ */
...@@ -98,21 +107,13 @@ constexpr spawn_options blocking_api = spawn_options::blocking_api_flag; ...@@ -98,21 +107,13 @@ constexpr spawn_options blocking_api = spawn_options::blocking_api_flag;
* @brief Causes the new actor to evaluate message priorities. * @brief Causes the new actor to evaluate message priorities.
* @note This implicitly causes the actor to run in its own thread. * @note This implicitly causes the actor to run in its own thread.
*/ */
constexpr spawn_options priority_aware = spawn_options::priority_aware_flag; constexpr spawn_options priority_aware = spawn_options::priority_aware_flag
+ spawn_options::detach_flag;
#ifndef CPPA_DOCUMENTATION #ifndef CPPA_DOCUMENTATION
} // namespace <anonymous> } // namespace <anonymous>
#endif #endif
/**
* @brief Concatenates two {@link spawn_options}.
* @relates spawn_options
*/
constexpr spawn_options operator+(const spawn_options& lhs,
const spawn_options& rhs) {
return static_cast<spawn_options>(static_cast<int>(lhs) | static_cast<int>(rhs));
}
/** /**
* @brief Checks wheter @p haystack contains @p needle. * @brief Checks wheter @p haystack contains @p needle.
* @relates spawn_options * @relates spawn_options
......
...@@ -61,13 +61,7 @@ actor::actor(actor_id aid) ...@@ -61,13 +61,7 @@ actor::actor(actor_id aid)
actor::actor() actor::actor()
: m_id(get_actor_registry()->next_id()), m_is_proxy(false) : m_id(get_actor_registry()->next_id()), m_is_proxy(false)
, m_exit_reason(exit_reason::not_exited) { , m_exit_reason(exit_reason::not_exited) { }
CPPA_LOGMF(CPPA_INFO, self, "spawned new local actor with ID " << m_id);
}
actor::~actor() {
CPPA_LOG_INFO("ID = " << m_id << "");
}
bool actor::link_to_impl(const actor_ptr& other) { bool actor::link_to_impl(const actor_ptr& other) {
if (other && other != this) { if (other && other != this) {
...@@ -173,6 +167,8 @@ bool actor::unlink_from_impl(const actor_ptr& other) { ...@@ -173,6 +167,8 @@ bool actor::unlink_from_impl(const actor_ptr& other) {
} }
void actor::cleanup(std::uint32_t reason) { void actor::cleanup(std::uint32_t reason) {
// log as 'actor'
CPPA_LOGM_TRACE("cppa::actor", CPPA_ARG(m_id) << ", " << CPPA_ARG(reason));
CPPA_REQUIRE(reason != exit_reason::not_exited); CPPA_REQUIRE(reason != exit_reason::not_exited);
// move everyhting out of the critical section before processing it // move everyhting out of the critical section before processing it
decltype(m_links) mlinks; decltype(m_links) mlinks;
...@@ -190,14 +186,16 @@ void actor::cleanup(std::uint32_t reason) { ...@@ -190,14 +186,16 @@ void actor::cleanup(std::uint32_t reason) {
m_links.clear(); m_links.clear();
m_attachables.clear(); m_attachables.clear();
} }
CPPA_LOG_INFO((is_proxy() ? "proxy" : "local") CPPA_LOGC_INFO_IF(not is_proxy(), "cppa::actor", __func__,
<< " actor had " << mlinks.size() << " links and " "actor with ID " << m_id << " had " << mlinks.size()
<< mattachables.size() << " attached functors; " << " links and " << mattachables.size()
<< CPPA_ARG(reason) << ", " << CPPA_ARG(m_id)); << " attached functors; exit reason = " << reason
<< ", class = " << detail::demangle(typeid(*this)));
// send exit messages // send exit messages
auto msg = make_any_tuple(atom("EXIT"), reason); auto msg = make_any_tuple(atom("EXIT"), reason);
for (actor_ptr& aptr : mlinks) { for (actor_ptr& aptr : mlinks) {
send_tuple_as(this, aptr, msg); message_header hdr{this, aptr, message_priority::high};
hdr.deliver(msg);
} }
for (attachable_ptr& ptr : mattachables) { for (attachable_ptr& ptr : mattachables) {
ptr->actor_exited(reason); ptr->actor_exited(reason);
......
...@@ -59,11 +59,11 @@ default_actor_proxy::default_actor_proxy(actor_id mid, ...@@ -59,11 +59,11 @@ default_actor_proxy::default_actor_proxy(actor_id mid,
} }
default_actor_proxy::~default_actor_proxy() { default_actor_proxy::~default_actor_proxy() {
auto aid = id(); auto aid = m_id;
auto node = m_pinf; auto node = m_pinf;
auto proto = m_proto; auto proto = m_proto;
CPPA_LOG_INFO(CPPA_ARG(m_id) << ", " << CPPA_TARG(m_pinf, to_string) CPPA_LOG_INFO(CPPA_ARG(m_id) << ", " << CPPA_TSARG(m_pinf)
<< "protocol = " << detail::demangle(typeid(*m_proto))); << ", protocol = " << detail::demangle(typeid(*m_proto)));
proto->run_later([aid, node, proto] { proto->run_later([aid, node, proto] {
CPPA_LOGC_TRACE("cppa::network::default_actor_proxy", CPPA_LOGC_TRACE("cppa::network::default_actor_proxy",
"~default_actor_proxy$run_later", "~default_actor_proxy$run_later",
...@@ -94,8 +94,14 @@ void default_actor_proxy::deliver(const message_header& hdr, any_tuple msg) { ...@@ -94,8 +94,14 @@ void default_actor_proxy::deliver(const message_header& hdr, any_tuple msg) {
} }
void default_actor_proxy::forward_msg(const message_header& hdr, any_tuple msg) { void default_actor_proxy::forward_msg(const message_header& hdr, any_tuple msg) {
CPPA_LOG_TRACE(""); CPPA_LOG_TRACE(CPPA_ARG(m_id) << ", " << CPPA_TSARG(hdr)
CPPA_REQUIRE(hdr.receiver == this); << ", " << CPPA_TSARG(msg));
if (hdr.receiver != this) {
auto cpy = hdr;
cpy.receiver = this;
forward_msg(cpy, std::move(msg));
return;
}
if (hdr.sender && hdr.id.is_request()) { if (hdr.sender && hdr.id.is_request()) {
switch (m_pending_requests.enqueue(new_req_info(hdr.sender, hdr.id))) { switch (m_pending_requests.enqueue(new_req_info(hdr.sender, hdr.id))) {
case intrusive::queue_closed: { case intrusive::queue_closed: {
......
...@@ -254,9 +254,6 @@ void default_peer::kill_proxy(const actor_ptr& sender, ...@@ -254,9 +254,6 @@ void default_peer::kill_proxy(const actor_ptr& sender,
CPPA_LOGMF(CPPA_DEBUG, self, "received KILL_PROXY for " << aid CPPA_LOGMF(CPPA_DEBUG, self, "received KILL_PROXY for " << aid
<< ":" << to_string(*node)); << ":" << to_string(*node));
send_as(nullptr, proxy, atom("KILL_PROXY"), reason); send_as(nullptr, proxy, atom("KILL_PROXY"), reason);
/*proxy->enqueue(nullptr,
make_any_tuple(
atom("KILL_PROXY"), reason));*/
} }
else { else {
CPPA_LOG_INFO("received KILL_PROXY message but " CPPA_LOG_INFO("received KILL_PROXY message but "
...@@ -271,24 +268,6 @@ void default_peer::deliver(const message_header& hdr, any_tuple msg) { ...@@ -271,24 +268,6 @@ void default_peer::deliver(const message_header& hdr, any_tuple msg) {
hdr.sender.downcast<actor_proxy>()->deliver(hdr, std::move(msg)); hdr.sender.downcast<actor_proxy>()->deliver(hdr, std::move(msg));
} }
else hdr.deliver(std::move(msg)); else hdr.deliver(std::move(msg));
/*
auto receiver = hdr.receiver.get();
if (receiver) {
if (hdr.id.valid()) {
CPPA_LOGMF(CPPA_DEBUG, self, "sync message for actor " << receiver->id());
receiver->sync_enqueue(hdr.sender.get(), hdr.id, move(msg));
}
else {
CPPA_LOGMF(CPPA_DEBUG, self, "async message with "
<< (hdr.sender ? "" : "in")
<< "valid sender");
receiver->enqueue(hdr.sender.get(), move(msg));
}
}
else {
CPPA_LOGMF(CPPA_ERROR, self, "received message with invalid receiver");
}
*/
} }
void default_peer::link(const actor_ptr& sender, const actor_ptr& ptr) { void default_peer::link(const actor_ptr& sender, const actor_ptr& ptr) {
......
...@@ -193,7 +193,7 @@ actor_ptr default_protocol::remote_actor(io_stream_ptr_pair io, ...@@ -193,7 +193,7 @@ actor_ptr default_protocol::remote_actor(io_stream_ptr_pair io,
if (*pinf == *pinfptr) { if (*pinf == *pinfptr) {
// dude, this is not a remote actor, it's a local actor! // dude, this is not a remote actor, it's a local actor!
CPPA_LOGMF(CPPA_ERROR, self, "remote_actor() called to access a local actor"); CPPA_LOGMF(CPPA_ERROR, self, "remote_actor() called to access a local actor");
# ifndef CPPA_ENABLE_DEBUG # ifndef CPPA_DEBUG_MODE
std::cerr << "*** warning: remote_actor() called to access a local actor\n" std::cerr << "*** warning: remote_actor() called to access a local actor\n"
<< std::flush; << std::flush;
# endif # endif
......
...@@ -181,10 +181,10 @@ class local_broker : public event_based_actor { ...@@ -181,10 +181,10 @@ class local_broker : public event_based_actor {
// send to all remote subscribers // send to all remote subscribers
auto sender = last_sender(); auto sender = last_sender();
CPPA_LOG_DEBUG("forward message to " << m_acquaintances.size() CPPA_LOG_DEBUG("forward message to " << m_acquaintances.size()
<< " acquaintances; " << CPPA_TTARG(sender) << " acquaintances; " << CPPA_TSARG(sender)
<< ", " << CPPA_TTARG(what)); << ", " << CPPA_TSARG(what));
for (auto& acquaintance : m_acquaintances) { for (auto& acquaintance : m_acquaintances) {
send_tuple_as(sender, acquaintance, what); acquaintance->enqueue({sender, acquaintance}, what);
} }
} }
...@@ -216,7 +216,7 @@ class local_group_proxy : public local_group { ...@@ -216,7 +216,7 @@ class local_group_proxy : public local_group {
} }
group::subscription subscribe(const channel_ptr& who) { group::subscription subscribe(const channel_ptr& who) {
CPPA_LOG_TRACE(CPPA_TTARG(who)); CPPA_LOG_TRACE(CPPA_TSARG(who));
auto res = add_subscriber(who); auto res = add_subscriber(who);
if (res.first) { if (res.first) {
if (res.second == 1) { if (res.second == 1) {
...@@ -229,7 +229,7 @@ class local_group_proxy : public local_group { ...@@ -229,7 +229,7 @@ class local_group_proxy : public local_group {
} }
void unsubscribe(const channel_ptr& who) { void unsubscribe(const channel_ptr& who) {
CPPA_LOG_TRACE(CPPA_TTARG(who)); CPPA_LOG_TRACE(CPPA_TSARG(who));
auto res = erase_subscriber(who); auto res = erase_subscriber(who);
if (res.first && res.second == 0) { if (res.first && res.second == 0) {
// leave the remote source, // leave the remote source,
...@@ -358,7 +358,7 @@ class remote_group : public group { ...@@ -358,7 +358,7 @@ class remote_group : public group {
: super(parent, move(id)), m_decorated(decorated) { } : super(parent, move(id)), m_decorated(decorated) { }
group::subscription subscribe(const channel_ptr& who) { group::subscription subscribe(const channel_ptr& who) {
CPPA_LOG_TRACE(CPPA_TTARG(who)); CPPA_LOG_TRACE(CPPA_TSARG(who));
return m_decorated->subscribe(who); return m_decorated->subscribe(who);
} }
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
\******************************************************************************/ \******************************************************************************/
#include <string>
#include "cppa/cppa.hpp" #include "cppa/cppa.hpp"
#include "cppa/atom.hpp" #include "cppa/atom.hpp"
#include "cppa/logging.hpp" #include "cppa/logging.hpp"
...@@ -54,8 +55,8 @@ class down_observer : public attachable { ...@@ -54,8 +55,8 @@ class down_observer : public attachable {
void actor_exited(std::uint32_t reason) { void actor_exited(std::uint32_t reason) {
if (m_observer) { if (m_observer) {
m_observer->enqueue(m_observed.get(), message_header hdr{m_observed, m_observer, message_priority::high};
make_any_tuple(atom("DOWN"), reason)); hdr.deliver(make_any_tuple(atom("DOWN"), reason));
} }
} }
...@@ -69,11 +70,41 @@ class down_observer : public attachable { ...@@ -69,11 +70,41 @@ class down_observer : public attachable {
}; };
constexpr const char* s_default_debug_name = "actor";
} // namespace <anonymous> } // namespace <anonymous>
local_actor::local_actor(bool sflag) local_actor::local_actor(bool sflag)
: m_chaining(sflag), m_trap_exit(false) : m_chaining(sflag), m_trap_exit(false)
, m_is_scheduled(sflag), m_dummy_node(), m_current_node(&m_dummy_node) { } , m_is_scheduled(sflag), m_dummy_node(), m_current_node(&m_dummy_node) {
# ifdef CPPA_DEBUG_MODE
new (&m_debug_name) std::string (std::to_string(m_id) + "@local");
# endif // CPPA_DEBUG_MODE
}
local_actor::~local_actor() {
using std::string;
# ifdef CPPA_DEBUG_MODE
m_debug_name.~string();
# endif // CPPA_DEBUG_MODE
}
const char* local_actor::debug_name() const {
# ifdef CPPA_DEBUG_MODE
return m_debug_name.c_str();
# else // CPPA_DEBUG_MODE
return s_default_debug_name;
# endif // CPPA_DEBUG_MODE
}
void local_actor::debug_name(std::string str) {
# ifdef CPPA_DEBUG_MODE
m_debug_name = std::move(str);
# else // CPPA_DEBUG_MODE
CPPA_LOG_WARNING("unable to set debug name to " << str
<< " (compiled without debug mode enabled)");
# endif // CPPA_DEBUG_MODE
}
void local_actor::monitor(const actor_ptr& whom) { void local_actor::monitor(const actor_ptr& whom) {
if (whom) whom->attach(attachable_ptr{new down_observer(this, whom)}); if (whom) whom->attach(attachable_ptr{new down_observer(this, whom)});
...@@ -141,17 +172,6 @@ response_handle local_actor::make_response_handle() { ...@@ -141,17 +172,6 @@ response_handle local_actor::make_response_handle() {
return std::move(result); return std::move(result);
} }
/*
message_id local_actor::send_timed_sync_message(const actor_ptr& whom,
const util::duration& rel_time,
any_tuple&& what) {
auto mid = this->send_sync_message(whom, std::move(what));
auto tmp = make_any_tuple(atom("TIMEOUT"));
get_scheduler()->delayed_reply(this, rel_time, mid, std::move(tmp));
return mid;
}
*/
void local_actor::exec_behavior_stack() { void local_actor::exec_behavior_stack() {
// default implementation does nothing // default implementation does nothing
} }
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include <ctime> #include <ctime>
#include <thread> #include <thread>
#include <cstring>
#include <fstream> #include <fstream>
#include <algorithm> #include <algorithm>
...@@ -85,7 +86,7 @@ class logging_impl : public logging { ...@@ -85,7 +86,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::out | ios::app);
unique_ptr<log_event> event; unique_ptr<log_event> event;
for (;;) { for (;;) {
event.reset(m_queue.pop()); event.reset(m_queue.pop());
...@@ -117,9 +118,18 @@ class logging_impl : public logging { ...@@ -117,9 +118,18 @@ class logging_impl : public logging {
} }
else file_name = move(full_file_name); else file_name = move(full_file_name);
auto print_from = [&](ostream& oss) -> ostream& { auto print_from = [&](ostream& oss) -> ostream& {
if (!from) oss << "null"; if (!from) {
if (strcmp(c_class_name, "logging") == 0) oss << "logging";
else oss << "null";
}
else if (from->is_proxy()) oss << to_string(from); else if (from->is_proxy()) oss << to_string(from);
else oss << from->id() << "@local"; else {
# ifdef CPPA_DEBUG_MODE
oss << from.downcast<local_actor>()->debug_name();
# else // CPPA_DEBUG_MODE
oss << from->id() << "@local";
# endif // CPPA_DEBUG_MODE
}
return oss; return oss;
}; };
ostringstream line; ostringstream line;
......
...@@ -45,6 +45,7 @@ ...@@ -45,6 +45,7 @@
#include "cppa/actor_proxy.hpp" #include "cppa/actor_proxy.hpp"
#include "cppa/binary_serializer.hpp" #include "cppa/binary_serializer.hpp"
#include "cppa/uniform_type_info.hpp" #include "cppa/uniform_type_info.hpp"
#include "cppa/thread_mapped_actor.hpp"
#include "cppa/binary_deserializer.hpp" #include "cppa/binary_deserializer.hpp"
#include "cppa/process_information.hpp" #include "cppa/process_information.hpp"
...@@ -559,6 +560,11 @@ void abstract_middleman::stop_reader(const continuable_reader_ptr& ptr) { ...@@ -559,6 +560,11 @@ void abstract_middleman::stop_reader(const continuable_reader_ptr& ptr) {
} }
void middleman_loop(middleman_impl* impl) { void middleman_loop(middleman_impl* impl) {
# ifdef CPPA_LOG_LEVEL
auto mself = make_counted<thread_mapped_actor>();
scoped_self_setter sss(mself.get());
CPPA_SET_DEBUG_NAME("middleman");
# endif
middleman_event_handler* handler = &impl->m_handler; middleman_event_handler* handler = &impl->m_handler;
CPPA_LOGF_TRACE("run middleman loop"); CPPA_LOGF_TRACE("run middleman loop");
CPPA_LOGF_INFO("middleman runs at " CPPA_LOGF_INFO("middleman runs at "
......
...@@ -93,7 +93,7 @@ program program::create(const char* kernel_source) { ...@@ -93,7 +93,7 @@ program program::create(const char* kernel_source) {
throw std::runtime_error(oss.str()); throw std::runtime_error(oss.str());
} }
else { else {
# ifdef CPPA_ENABLE_DEBUG # ifdef CPPA_DEBUG_MODE
device_ptr device_used(cppa::detail::singleton_manager:: device_ptr device_used(cppa::detail::singleton_manager::
get_command_dispatcher()-> get_command_dispatcher()->
m_devices.front().dev_id); m_devices.front().dev_id);
......
...@@ -177,7 +177,7 @@ void scheduler_helper::timer_loop(scheduler_helper::ptr_type m_self) { ...@@ -177,7 +177,7 @@ void scheduler_helper::timer_loop(scheduler_helper::ptr_type m_self) {
done = true; done = true;
}, },
others() >> [&]() { others() >> [&]() {
# ifdef CPPA_ENABLE_DEBUG # ifdef CPPA_DEBUG_MODE
std::cerr << "scheduler_helper::timer_loop: UNKNOWN MESSAGE: " std::cerr << "scheduler_helper::timer_loop: UNKNOWN MESSAGE: "
<< to_string(msg_ptr->msg) << to_string(msg_ptr->msg)
<< std::endl; << std::endl;
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include <pthread.h> #include <pthread.h>
#include "cppa/self.hpp" #include "cppa/self.hpp"
#include "cppa/logging.hpp"
#include "cppa/any_tuple.hpp" #include "cppa/any_tuple.hpp"
#include "cppa/scheduler.hpp" #include "cppa/scheduler.hpp"
#include "cppa/local_actor.hpp" #include "cppa/local_actor.hpp"
...@@ -45,6 +46,7 @@ pthread_once_t s_key_once = PTHREAD_ONCE_INIT; ...@@ -45,6 +46,7 @@ pthread_once_t s_key_once = PTHREAD_ONCE_INIT;
local_actor* tss_constructor() { local_actor* tss_constructor() {
local_actor* result = detail::memory::create<thread_mapped_actor>(); local_actor* result = detail::memory::create<thread_mapped_actor>();
CPPA_LOGF_INFO("converted thread to actor; ID = " << result->id());
result->ref(); result->ref();
get_scheduler()->register_converted_context(result); get_scheduler()->register_converted_context(result);
return result; return result;
......
...@@ -77,32 +77,31 @@ std::atomic<logging*> s_logger; ...@@ -77,32 +77,31 @@ std::atomic<logging*> s_logger;
} // namespace <anonymous> } // namespace <anonymous>
void singleton_manager::shutdown() { void singleton_manager::shutdown() {
CPPA_LOGF_INFO("prepare to shutdown"); CPPA_LOGF(CPPA_DEBUG, nullptr, "prepare to shutdown");
if (self.unchecked() != nullptr) { if (self.unchecked() != nullptr) {
try { self.unchecked()->quit(exit_reason::normal); } try { self.unchecked()->quit(exit_reason::normal); }
catch (actor_exited&) { } catch (actor_exited&) { }
} }
//auto rptr = s_actor_registry.load(); //auto rptr = s_actor_registry.load();
//if (rptr) rptr->await_running_count_equal(0); //if (rptr) rptr->await_running_count_equal(0);
CPPA_LOGF_DEBUG("shutdown scheduler"); CPPA_LOGF(CPPA_DEBUG, nullptr, "shutdown scheduler");
destroy(s_scheduler); destroy(s_scheduler);
CPPA_LOGF_DEBUG("shutdown middleman"); CPPA_LOGF(CPPA_DEBUG, nullptr, "shutdown middleman");
destroy(s_middleman); destroy(s_middleman);
std::atomic_thread_fence(std::memory_order_seq_cst); std::atomic_thread_fence(std::memory_order_seq_cst);
// it's safe to delete all other singletons now // it's safe to delete all other singletons now
CPPA_LOGF_DEBUG("close OpenCL command dispather"); CPPA_LOGF(CPPA_DEBUG, nullptr, "close OpenCL command dispather");
destroy(s_command_dispatcher); destroy(s_command_dispatcher);
CPPA_LOGF_DEBUG("close actor registry"); CPPA_LOGF(CPPA_DEBUG, nullptr, "close actor registry");
destroy(s_actor_registry); destroy(s_actor_registry);
CPPA_LOGF_DEBUG("shutdown group manager"); CPPA_LOGF(CPPA_DEBUG, nullptr, "shutdown group manager");
destroy(s_group_manager); destroy(s_group_manager);
CPPA_LOGF_DEBUG("destroy empty tuple singleton"); CPPA_LOGF(CPPA_DEBUG, nullptr, "destroy empty tuple singleton");
destroy(s_empty_tuple); destroy(s_empty_tuple);
CPPA_LOGF_DEBUG("clear type info map"); CPPA_LOGF(CPPA_DEBUG, nullptr, "clear type info map");
destroy(s_uniform_type_info_map); destroy(s_uniform_type_info_map);
CPPA_LOGF_DEBUG("clear decorated names log"); CPPA_LOGF(CPPA_DEBUG, nullptr, "clear decorated names log");
destroy(s_decorated_names_map); destroy(s_decorated_names_map);
CPPA_LOGF_DEBUG("shutdown logger");
destroy(s_logger); destroy(s_logger);
} }
......
...@@ -200,7 +200,7 @@ void exec_as_thread(bool is_hidden, local_actor_ptr p, F f) { ...@@ -200,7 +200,7 @@ void exec_as_thread(bool is_hidden, local_actor_ptr p, F f) {
}).detach(); }).detach();
} }
actor_ptr thread_pool_scheduler::exec(spawn_options os, scheduled_actor_ptr p) { local_actor_ptr thread_pool_scheduler::exec(spawn_options os, scheduled_actor_ptr p) {
CPPA_REQUIRE(p != nullptr); CPPA_REQUIRE(p != nullptr);
bool is_hidden = has_hide_flag(os); bool is_hidden = has_hide_flag(os);
if (has_detach_flag(os)) { if (has_detach_flag(os)) {
...@@ -219,35 +219,62 @@ actor_ptr thread_pool_scheduler::exec(spawn_options os, scheduled_actor_ptr p) { ...@@ -219,35 +219,62 @@ actor_ptr thread_pool_scheduler::exec(spawn_options os, scheduled_actor_ptr p) {
return std::move(p); return std::move(p);
} }
actor_ptr thread_pool_scheduler::exec(spawn_options os, local_actor_ptr thread_pool_scheduler::exec(spawn_options os,
init_callback cb, init_callback cb,
void_function f) { void_function f) {
if (has_blocking_api_flag(os)) { local_actor_ptr result;
auto set_result = [&](local_actor_ptr value) {
CPPA_REQUIRE(result == nullptr && value != nullptr);
result = std::move(value);
if (cb) cb(result.get());
};
if (has_priority_aware_flag(os)) {
using impl = extend<thread_mapped_actor>::with<prioritizing>;
set_result(make_counted<impl>());
exec_as_thread(has_hide_flag(os), result, [result, f] {
try {
f();
result->exec_behavior_stack();
}
catch (actor_exited& e) { }
catch (std::exception& e) {
CPPA_LOGF_ERROR("actor with ID " << result->id()
<< " terminated due to an unhandled exception; "
<< detail::demangle(typeid(e)) << ": "
<< e.what());
}
catch (...) {
CPPA_LOGF_ERROR("actor with ID " << result->id()
<< " terminated due to an unknown exception");
}
result->on_exit();
});
}
else if (has_blocking_api_flag(os)) {
# ifndef CPPA_DISABLE_CONTEXT_SWITCHING # ifndef CPPA_DISABLE_CONTEXT_SWITCHING
if (!has_detach_flag(os)) { if (!has_detach_flag(os)) {
return exec(os, make_counted<context_switching_actor>(std::move(f))); auto p = make_counted<context_switching_actor>(std::move(f));
set_result(p);
exec(os, std::move(p));
} }
else
# endif # endif
/* else tree */ {
auto p = make_counted<thread_mapped_actor>(std::move(f)); auto p = make_counted<thread_mapped_actor>(std::move(f));
set_result(p);
exec_as_thread(has_hide_flag(os), p, [p] { exec_as_thread(has_hide_flag(os), p, [p] {
p->run(); p->run();
p->on_exit(); p->on_exit();
}); });
return std::move(p);
} }
else if (has_priority_aware_flag(os)) {
using impl = extend<thread_mapped_actor>::with<prioritizing>;
auto p = make_counted<impl>();
exec_as_thread(has_hide_flag(os), p, [p, f] {
f();
p->exec_behavior_stack();
p->on_exit();
});
return std::move(p);
} }
else {
auto p = event_based_actor::from(std::move(f)); auto p = event_based_actor::from(std::move(f));
if (cb) cb(p.get()); set_result(p);
return exec(os, p); exec(os, p);
}
CPPA_REQUIRE(result != nullptr);
return std::move(result);
} }
} } // namespace cppa::detail } } // namespace cppa::detail
...@@ -354,7 +354,6 @@ class msg_hdr_tinfo : public util::abstract_uniform_type_info<message_header> { ...@@ -354,7 +354,6 @@ class msg_hdr_tinfo : public util::abstract_uniform_type_info<message_header> {
public: public:
virtual void serialize(const void* instance, serializer* sink) const { virtual void serialize(const void* instance, serializer* sink) const {
CPPA_LOG_TRACE("");
auto& hdr = *reinterpret_cast<const message_header*>(instance); auto& hdr = *reinterpret_cast<const message_header*>(instance);
sink->begin_object(name()); sink->begin_object(name());
actor_ptr_tinfo::s_serialize(hdr.sender, sink); actor_ptr_tinfo::s_serialize(hdr.sender, sink);
...@@ -364,7 +363,6 @@ class msg_hdr_tinfo : public util::abstract_uniform_type_info<message_header> { ...@@ -364,7 +363,6 @@ class msg_hdr_tinfo : public util::abstract_uniform_type_info<message_header> {
} }
virtual void deserialize(void* instance, deserializer* source) const { virtual void deserialize(void* instance, deserializer* source) const {
CPPA_LOG_TRACE("");
assert_type_name(source); assert_type_name(source);
source->begin_object(name()); source->begin_object(name());
auto& msg = *reinterpret_cast<message_header*>(instance); auto& msg = *reinterpret_cast<message_header*>(instance);
......
...@@ -16,7 +16,6 @@ namespace { ...@@ -16,7 +16,6 @@ namespace {
size_t s_pongs = 0; size_t s_pongs = 0;
behavior ping_behavior(size_t num_pings) { behavior ping_behavior(size_t num_pings) {
CPPA_LOGF_TRACE("");
return ( return (
on(atom("pong"), arg_match) >> [num_pings](int value) { on(atom("pong"), arg_match) >> [num_pings](int value) {
CPPA_LOGF_ERROR_IF(!self->last_sender(), "last_sender() == nullptr"); CPPA_LOGF_ERROR_IF(!self->last_sender(), "last_sender() == nullptr");
...@@ -39,13 +38,12 @@ behavior ping_behavior(size_t num_pings) { ...@@ -39,13 +38,12 @@ behavior ping_behavior(size_t num_pings) {
} }
behavior pong_behavior() { behavior pong_behavior() {
CPPA_LOGF_TRACE("");
return ( return (
on<atom("ping"), int>() >> [](int value) { on(atom("ping"), arg_match) >> [](int value) {
CPPA_LOGF_INFO("received {'ping', " << value << "}"); CPPA_LOGF_INFO("received {'ping', " << value << "}");
reply(atom("pong"), value + 1); reply(atom("pong"), value + 1);
}, },
others() >> []() { others() >> [] {
CPPA_LOGF_ERROR("unexpected message; " CPPA_LOGF_ERROR("unexpected message; "
<< to_string(self->last_dequeued())); << to_string(self->last_dequeued()));
self->quit(exit_reason::user_defined); self->quit(exit_reason::user_defined);
...@@ -60,31 +58,30 @@ size_t pongs() { ...@@ -60,31 +58,30 @@ size_t pongs() {
} }
void ping(size_t num_pings) { void ping(size_t num_pings) {
CPPA_SET_DEBUG_NAME("ping");
CPPA_LOGF_TRACE("num_pings = " << num_pings); CPPA_LOGF_TRACE("num_pings = " << num_pings);
s_pongs = 0; s_pongs = 0;
receive_loop(ping_behavior(num_pings)); receive_loop(ping_behavior(num_pings));
} }
actor_ptr spawn_event_based_ping(size_t num_pings) { void event_based_ping(size_t num_pings) {
CPPA_SET_DEBUG_NAME("event_based_ping");
CPPA_LOGF_TRACE("num_pings = " << num_pings); CPPA_LOGF_TRACE("num_pings = " << num_pings);
s_pongs = 0; s_pongs = 0;
return spawn([=] {
become(ping_behavior(num_pings)); become(ping_behavior(num_pings));
});
} }
void pong(actor_ptr ping_actor) { void pong(actor_ptr ping_actor) {
CPPA_SET_DEBUG_NAME("pong");
CPPA_LOGF_TRACE("ping_actor = " << to_string(ping_actor)); CPPA_LOGF_TRACE("ping_actor = " << to_string(ping_actor));
// kickoff send(ping_actor, atom("pong"), 0); // kickoff
send(ping_actor, atom("pong"), 0); receive_loop(pong_behavior());
receive_loop (pong_behavior());
} }
actor_ptr spawn_event_based_pong(actor_ptr ping_actor) { void event_based_pong(actor_ptr ping_actor) {
CPPA_SET_DEBUG_NAME("event_based_pong");
CPPA_LOGF_TRACE("ping_actor = " << to_string(ping_actor)); CPPA_LOGF_TRACE("ping_actor = " << to_string(ping_actor));
CPPA_REQUIRE(ping_actor.get() != nullptr); CPPA_REQUIRE(ping_actor != nullptr);
return factory::event_based([=] { send(ping_actor, atom("pong"), 0); // kickoff
become(pong_behavior()); become(pong_behavior());
send(ping_actor, atom("pong"), 0);
}).spawn();
} }
...@@ -8,11 +8,11 @@ ...@@ -8,11 +8,11 @@
void ping(size_t num_pings); void ping(size_t num_pings);
cppa::actor_ptr spawn_event_based_ping(size_t num_pings); void event_based_ping(size_t num_pings);
void pong(cppa::actor_ptr ping_actor); void pong(cppa::actor_ptr ping_actor);
cppa::actor_ptr spawn_event_based_pong(cppa::actor_ptr ping_actor); void event_based_pong(cppa::actor_ptr ping_actor);
// returns the number of messages ping received // returns the number of messages ping received
size_t pongs(); size_t pongs();
......
...@@ -102,7 +102,7 @@ inline void cppa_check_value(V1 v1, ...@@ -102,7 +102,7 @@ inline void cppa_check_value(V1 v1,
auto cppa_test_scope_guard = ::cppa::util::make_scope_guard([] { \ auto cppa_test_scope_guard = ::cppa::util::make_scope_guard([] { \
std::cout << cppa_error_count() << " error(s) detected" << std::endl; \ std::cout << cppa_error_count() << " error(s) detected" << std::endl; \
}); \ }); \
CPPA_LOGF(CPPA_TRACE, nullptr, "run unit test " << #testname) CPPA_LOGF_INFO("run unit test " << #testname)
#define CPPA_TEST_RESULT() ((cppa_error_count() == 0) ? 0 : -1) #define CPPA_TEST_RESULT() ((cppa_error_count() == 0) ? 0 : -1)
...@@ -120,7 +120,7 @@ inline void cppa_check_value(V1 v1, ...@@ -120,7 +120,7 @@ inline void cppa_check_value(V1 v1,
CPPA_PRINTERR(#line_of_code); \ CPPA_PRINTERR(#line_of_code); \
cppa_inc_error_count(); \ cppa_inc_error_count(); \
} \ } \
else CPPA_PRINT("passed") else { CPPA_PRINT("passed"); } CPPA_VOID_STMT
#define CPPA_CHECK_EQUAL(lhs_loc, rhs_loc) \ #define CPPA_CHECK_EQUAL(lhs_loc, rhs_loc) \
cppa_check_value((lhs_loc), (rhs_loc), __FILE__, __LINE__) cppa_check_value((lhs_loc), (rhs_loc), __FILE__, __LINE__)
......
This diff is collapsed.
...@@ -365,6 +365,7 @@ int main() { ...@@ -365,6 +365,7 @@ int main() {
CPPA_PRINT("test priority aware mirror"); { CPPA_PRINT("test priority aware mirror"); {
auto mirror = spawn<simple_mirror,monitored+priority_aware>(); auto mirror = spawn<simple_mirror,monitored+priority_aware>();
CPPA_CHECKPOINT();
send(mirror, "hello mirror"); send(mirror, "hello mirror");
receive ( receive (
on("hello mirror") >> CPPA_CHECKPOINT_CB(), on("hello mirror") >> CPPA_CHECKPOINT_CB(),
......
...@@ -77,7 +77,6 @@ struct B : popular_actor { ...@@ -77,7 +77,6 @@ struct B : popular_actor {
struct C : sb_actor<C> { struct C : sb_actor<C> {
behavior init_state = ( behavior init_state = (
on(atom("gogo")) >> [=] { on(atom("gogo")) >> [=] {
CPPA_CHECKPOINT();
reply(atom("gogogo")); reply(atom("gogogo"));
self->quit(); self->quit();
} }
......
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