Commit 63eb3af5 authored by Dominik Charousset's avatar Dominik Charousset

started to re-implement basic libcppa features

parent c91bf3fc
...@@ -88,12 +88,15 @@ endif () ...@@ -88,12 +88,15 @@ endif ()
if (ENABLE_DEBUG) if (ENABLE_DEBUG)
set(CMAKE_BUILD_TYPE Debug) set(CMAKE_BUILD_TYPE Debug)
add_definitions(-DCPPA_DEBUG_MODE) add_definitions(-DCPPA_DEBUG_MODE)
message(STATUS "----- configured using --enable-debug")
endif (ENABLE_DEBUG) endif (ENABLE_DEBUG)
if (CPPA_LOG_LEVEL) if (CPPA_LOG_LEVEL)
add_definitions(-DCPPA_LOG_LEVEL=${CPPA_LOG_LEVEL}) add_definitions(-DCPPA_LOG_LEVEL=${CPPA_LOG_LEVEL})
endif(CPPA_LOG_LEVEL) endif(CPPA_LOG_LEVEL)
message(STATUS "BLUBB: ${CMAKE_BUILD_TYPE}")
# set build default build type if not set # set build default build type if not set
if ("${CMAKE_BUILD_TYPE}" STREQUAL "") if ("${CMAKE_BUILD_TYPE}" STREQUAL "")
set(CMAKE_BUILD_TYPE RelWithDebInfo) set(CMAKE_BUILD_TYPE RelWithDebInfo)
......
...@@ -123,9 +123,9 @@ configure () ...@@ -123,9 +123,9 @@ configure ()
cd $workdir cd $workdir
if [ -n "$5" ]; then if [ -n "$5" ]; then
cmake -G "$5" "$CMakeCacheEntries" "$sourcedir" cmake -G "$5" $CMakeCacheEntries $sourcedir
else else
cmake "$CMakeCacheEntries" "$sourcedir" cmake $CMakeCacheEntries $sourcedir
fi fi
echo "# This is the command used to configure this build" > config.status echo "# This is the command used to configure this build" > config.status
...@@ -136,7 +136,6 @@ configure () ...@@ -136,7 +136,6 @@ configure ()
# Set defaults. # Set defaults.
builddir="$sourcedir/build" builddir="$sourcedir/build"
CMakeCacheEntries="" CMakeCacheEntries=""
append_cache_entry CMAKE_BUILD_TYPE STRING RelWithDebInfo
append_cache_entry CMAKE_INSTALL_PREFIX PATH /usr/local append_cache_entry CMAKE_INSTALL_PREFIX PATH /usr/local
append_cache_entry ENABLE_DEBUG BOOL false append_cache_entry ENABLE_DEBUG BOOL false
append_cache_entry DISABLE_CONTEXT_SWITCHING BOOL false append_cache_entry DISABLE_CONTEXT_SWITCHING BOOL false
......
...@@ -43,6 +43,7 @@ class node_id; ...@@ -43,6 +43,7 @@ class node_id;
class behavior; class behavior;
class any_tuple; class any_tuple;
class self_type; class self_type;
class actor_addr;
class actor_proxy; class actor_proxy;
class untyped_actor; class untyped_actor;
class abstract_actor; class abstract_actor;
......
...@@ -22,9 +22,8 @@ template<class Base, ...@@ -22,9 +22,8 @@ template<class Base,
class SchedulingPolicy, class SchedulingPolicy,
class PriorityPolicy, class PriorityPolicy,
class ResumePolicy, class ResumePolicy,
class InvokePolicy, class InvokePolicy>
bool OverrideDequeue = std::is_base_of<blocking_untyped_actor, Base>::value> class proper_actor_base : public ResumePolicy::template mixin<Base> {
class proper_actor : public ResumePolicy::template mixin<Base> {
friend SchedulingPolicy; friend SchedulingPolicy;
friend PriorityPolicy; friend PriorityPolicy;
...@@ -36,22 +35,16 @@ class proper_actor : public ResumePolicy::template mixin<Base> { ...@@ -36,22 +35,16 @@ class proper_actor : public ResumePolicy::template mixin<Base> {
public: public:
template <typename... Ts> template <typename... Ts>
proper_actor(Ts&&... args) : super(std::forward<Ts>(args)...) { } proper_actor_base(Ts&&... args) : super(std::forward<Ts>(args)...) { }
void enqueue(const message_header& hdr, any_tuple msg) override { void enqueue(const message_header& hdr, any_tuple msg) override {
m_scheduling_policy.enqueue(this, hdr, msg); m_scheduling_policy.enqueue(this, hdr, msg);
} }
inline void launch() { m_scheduling_policy.launch(this); }
inline mailbox_element* next_message() { inline mailbox_element* next_message() {
return m_priority_policy.next_message(this); return m_priority_policy.next_message(this);
} }
inline void invoke(mailbox_element* msg) {
m_invoke_policy.invoke(this, msg);
}
// grant access to the actor's mailbox // grant access to the actor's mailbox
typename Base::mailbox_type& mailbox() { return this->m_mailbox; } typename Base::mailbox_type& mailbox() { return this->m_mailbox; }
...@@ -67,16 +60,10 @@ class proper_actor : public ResumePolicy::template mixin<Base> { ...@@ -67,16 +60,10 @@ class proper_actor : public ResumePolicy::template mixin<Base> {
m_scheduling_policy.push_timeout(); m_scheduling_policy.push_timeout();
} }
inline void current_node(mailbox_element* ptr) {
this->m_current_node = ptr;
}
inline void request_timeout(const util::duration& rel_timeout) { inline void request_timeout(const util::duration& rel_timeout) {
m_invoke_policy.request_timeout(this, rel_timeout); m_invoke_policy.request_timeout(this, rel_timeout);
} }
inline mailbox_element* current_node() { return this->m_current_node; }
detail::behavior_stack& bhvr_stack() { return this->m_bhvr_stack; } detail::behavior_stack& bhvr_stack() { return this->m_bhvr_stack; }
protected: protected:
...@@ -88,16 +75,49 @@ class proper_actor : public ResumePolicy::template mixin<Base> { ...@@ -88,16 +75,49 @@ class proper_actor : public ResumePolicy::template mixin<Base> {
}; };
template<class Base,
class SchedulingPolicy,
class PriorityPolicy,
class ResumePolicy,
class InvokePolicy,
bool OverrideDequeue = std::is_base_of<blocking_untyped_actor, Base>::value>
class proper_actor : public proper_actor_base<Base, SchedulingPolicy,
PriorityPolicy, ResumePolicy,
InvokePolicy> {
typedef proper_actor_base<Base, SchedulingPolicy, PriorityPolicy,
ResumePolicy, InvokePolicy>
super;
public:
template <typename... Ts>
proper_actor(Ts&&... args) : super(std::forward<Ts>(args)...) { }
detail::behavior_stack& bhvr_stack() { return this->m_bhvr_stack; }
inline void launch() {
this->bhvr_stack().push_back(this->make_behavior());
this->m_scheduling_policy.launch(this);
}
bool invoke(mailbox_element* msg) {
return this->m_invoke_policy.invoke(this, msg, bhvr_stack().back());
}
};
// for blocking actors, there's one more member function to implement // for blocking actors, there's one more member function to implement
template <class Base, class SchedulingPolicy, class PriorityPolicy, template <class Base, class SchedulingPolicy, class PriorityPolicy,
class ResumePolicy, class InvokePolicy> class ResumePolicy, class InvokePolicy>
class proper_actor< class proper_actor<
Base, SchedulingPolicy, PriorityPolicy, ResumePolicy, InvokePolicy, Base, SchedulingPolicy, PriorityPolicy, ResumePolicy, InvokePolicy,
true> final : public proper_actor<Base, SchedulingPolicy, PriorityPolicy, true> final : public proper_actor_base<Base, SchedulingPolicy,
ResumePolicy, InvokePolicy, false> { PriorityPolicy, ResumePolicy,
InvokePolicy> {
typedef proper_actor<Base, SchedulingPolicy, PriorityPolicy, typedef proper_actor_base<Base, SchedulingPolicy, PriorityPolicy,
ResumePolicy, InvokePolicy, false> ResumePolicy, InvokePolicy>
super; super;
public: public:
...@@ -105,6 +125,10 @@ class proper_actor< ...@@ -105,6 +125,10 @@ class proper_actor<
template <typename... Ts> template <typename... Ts>
proper_actor(Ts&&... args) : super(std::forward<Ts>(args)...) { } proper_actor(Ts&&... args) : super(std::forward<Ts>(args)...) { }
inline void launch() {
this->m_scheduling_policy.launch(this);
}
void dequeue(behavior& bhvr) override { void dequeue(behavior& bhvr) override {
if (bhvr.timeout().valid()) { if (bhvr.timeout().valid()) {
auto tout = auto tout =
......
...@@ -60,16 +60,16 @@ namespace cppa { namespace detail { ...@@ -60,16 +60,16 @@ namespace cppa { namespace detail {
// ordered according to demangled type name (see uniform_type_info_map.cpp) // ordered according to demangled type name (see uniform_type_info_map.cpp)
using mapped_type_list = util::type_list< using mapped_type_list = util::type_list<
bool, bool,
actor,
actor_addr,
any_tuple, any_tuple,
atom_value, atom_value,
actor,
channel, channel,
group_ptr, group_ptr,
node_id_ptr, node_id_ptr,
io::accept_handle, io::accept_handle,
io::connection_handle, io::connection_handle,
message_header, message_header,
std::nullptr_t,
unit_t, unit_t,
util::buffer, util::buffer,
util::duration, util::duration,
......
...@@ -343,6 +343,14 @@ class local_actor : public extend<abstract_actor>::with<memory_cached> { ...@@ -343,6 +343,14 @@ class local_actor : public extend<abstract_actor>::with<memory_cached> {
/** @cond PRIVATE */ /** @cond PRIVATE */
inline void current_node(mailbox_element* ptr) {
this->m_current_node = ptr;
}
inline mailbox_element* current_node() {
return this->m_current_node;
}
inline message_id new_request_id() { inline message_id new_request_id() {
auto result = ++m_last_request_id; auto result = ++m_last_request_id;
m_pending_responses.push_back(result.response_id()); m_pending_responses.push_back(result.response_id());
......
...@@ -59,7 +59,8 @@ class continue_helper { ...@@ -59,7 +59,8 @@ class continue_helper {
template<typename F> template<typename F>
continue_helper& continue_with(F) { continue_helper& continue_with(F) {
//FIXME
throw std::logic_error("not implemented yet");
} }
inline message_id get_message_id() const { inline message_id get_message_id() const {
......
...@@ -75,18 +75,14 @@ class context_switching_resume { ...@@ -75,18 +75,14 @@ class context_switching_resume {
for (;;) { for (;;) {
switch (call(&m_fiber, from)) { switch (call(&m_fiber, from)) {
case yield_state::done: { case yield_state::done: {
CPPA_REQUIRE(next_job == nullptr);
return resumable::done; return resumable::done;
} }
case yield_state::ready: { break; } case yield_state::ready: { break; }
case yield_state::blocked: { case yield_state::blocked: {
CPPA_REQUIRE(next_job == nullptr);
CPPA_REQUIRE(m_chained_actor == nullptr);
switch (this->cas_state(actor_state::about_to_block, switch (this->cas_state(actor_state::about_to_block,
actor_state::blocked)) { actor_state::blocked)) {
case actor_state::ready: { case actor_state::ready: {
// restore variables // restore variables
CPPA_REQUIRE(next_job == nullptr);
break; break;
} }
case actor_state::blocked: { case actor_state::blocked: {
......
...@@ -106,7 +106,6 @@ class cooperative_scheduling { ...@@ -106,7 +106,6 @@ class cooperative_scheduling {
switch (state) { switch (state) {
case actor_state::blocked: { case actor_state::blocked: {
if (set_ready()) { if (set_ready()) {
CPPA_REQUIRE(m_scheduler != nullptr);
//m_scheduler->enqueue(this); //m_scheduler->enqueue(this);
return; return;
} }
......
...@@ -57,6 +57,9 @@ class event_based_resume { ...@@ -57,6 +57,9 @@ class event_based_resume {
template<typename... Ts> template<typename... Ts>
mixin(Ts&&... args) : Base(std::forward<Ts>(args)...) { } mixin(Ts&&... args) : Base(std::forward<Ts>(args)...) { }
// implemented in detail::proper_actor
virtual bool invoke(mailbox_element* msg) = 0;
resumable::resume_result resume(util::fiber*) override { resumable::resume_result resume(util::fiber*) override {
CPPA_LOG_TRACE("id = " << this->id() CPPA_LOG_TRACE("id = " << this->id()
<< ", state = " << static_cast<int>(this->state())); << ", state = " << static_cast<int>(this->state()));
...@@ -81,13 +84,11 @@ class event_based_resume { ...@@ -81,13 +84,11 @@ class event_based_resume {
this->on_exit(); this->on_exit();
return true; return true;
}; };
CPPA_REQUIRE(next_job == nullptr);
try { try {
//auto e = m_mailbox.try_pop(); //auto e = m_mailbox.try_pop();
for (auto e = this->m_mailbox.try_pop(); ; e = this->m_mailbox.try_pop()) { for (auto e = this->m_mailbox.try_pop(); ; e = this->m_mailbox.try_pop()) {
//e = m_mailbox.try_pop(); //e = m_mailbox.try_pop();
if (e == nullptr) { if (e == nullptr) {
CPPA_REQUIRE(next_job == nullptr);
CPPA_LOGMF(CPPA_DEBUG, self, "no more element in mailbox; going to block"); CPPA_LOGMF(CPPA_DEBUG, self, "no more element in mailbox; going to block");
this->set_state(actor_state::about_to_block); this->set_state(actor_state::about_to_block);
std::atomic_thread_fence(std::memory_order_seq_cst); std::atomic_thread_fence(std::memory_order_seq_cst);
...@@ -97,9 +98,9 @@ class event_based_resume { ...@@ -97,9 +98,9 @@ class event_based_resume {
case actor_state::ready: case actor_state::ready:
// interrupted by arriving message // interrupted by arriving message
// restore members // restore members
CPPA_REQUIRE(m_chained_actor == nullptr); CPPA_LOG_DEBUG("switched back to ready: "
CPPA_LOGMF(CPPA_DEBUG, self, "switched back to ready: " "interrupted by "
"interrupted by arriving message"); "arriving message");
break; break;
case actor_state::blocked: case actor_state::blocked:
CPPA_LOGMF(CPPA_DEBUG, self, "set state successfully to blocked"); CPPA_LOGMF(CPPA_DEBUG, self, "set state successfully to blocked");
...@@ -116,21 +117,19 @@ class event_based_resume { ...@@ -116,21 +117,19 @@ class event_based_resume {
this->set_state(actor_state::ready); this->set_state(actor_state::ready);
} }
} }
/*
else { else {
if (this->bhvr_stack().invoke(m_recv_policy, this, e)) { if (this->invoke(e)) {
CPPA_LOG_DEBUG_IF(m_chained_actor, CPPA_LOG_DEBUG_IF(m_chained_actor,
"set actor with ID " "set actor with ID "
<< m_chained_actor->id() << m_chained_actor->id()
<< " as successor"); << " as successor");
if (this->bhvr_stack().empty() && done_cb()) { if (this->bhvr_stack().empty() && done_cb()) {
CPPA_LOGMF(CPPA_DEBUG, self, "behavior stack empty"); CPPA_LOGMF(CPPA_DEBUG, self, "behavior stack empty");
return resume_result::actor_done; return resume_result::done;
} }
this->bhvr_stack().cleanup(); this->bhvr_stack().cleanup();
} }
} }
*/
} }
} }
catch (actor_exited& what) { catch (actor_exited& what) {
......
...@@ -56,25 +56,30 @@ class nestable_invoke : public invoke_policy<nestable_invoke> { ...@@ -56,25 +56,30 @@ class nestable_invoke : public invoke_policy<nestable_invoke> {
public: public:
static inline bool hm_should_skip(pointer) { static inline bool hm_should_skip(pointer node) {
return false; return node->marked;
} }
template<class Client> template<class Actor>
static inline pointer hm_begin(Client* client, pointer node) { inline pointer hm_begin(Actor* self, pointer node) {
auto previous = client->current_node(); auto previous = self->m_current_node;
client->current_node(node); self->m_current_node = node;
push_timeout();
node->marked = true;
return previous; return previous;
} }
template<class Client> template<class Actor>
static inline void hm_cleanup(Client* client, pointer /*previous*/) { inline void hm_cleanup(Actor* self, pointer previous) {
client->current_node(&(client->m_dummy_node)); self->m_current_node->marked = false;
self->m_current_node = previous;
} }
template<class Client> template<class Actor>
static inline void hm_revert(Client* client, pointer previous) { inline void hm_revert(Actor* self, pointer previous) {
client->current_node(previous); self->m_current_node->marked = false;
self->m_current_node = previous;
pop_timeout();
} }
typedef std::chrono::high_resolution_clock::time_point timeout_type; typedef std::chrono::high_resolution_clock::time_point timeout_type;
......
...@@ -92,15 +92,20 @@ class no_scheduling { ...@@ -92,15 +92,20 @@ class no_scheduling {
template<class Actor> template<class Actor>
void enqueue(Actor* self, const message_header& hdr, any_tuple& msg) { void enqueue(Actor* self, const message_header& hdr, any_tuple& msg) {
std::cout << "enqueue\n";
auto ptr = self->new_mailbox_element(hdr, std::move(msg)); auto ptr = self->new_mailbox_element(hdr, std::move(msg));
switch (self->mailbox().enqueue(ptr)) { switch (self->mailbox().enqueue(ptr)) {
default:
std::cout << "enqueue: default case (do nothing)\n";
break;
case intrusive::first_enqueued: { case intrusive::first_enqueued: {
std::cout << "enqueue: first enqueue -> notify\n";
lock_type guard(m_mtx); lock_type guard(m_mtx);
m_cv.notify_one(); m_cv.notify_one();
break; break;
} }
default: break;
case intrusive::queue_closed: case intrusive::queue_closed:
std::cout << "enqueue: mailbox closed!\n";
if (hdr.id.valid()) { if (hdr.id.valid()) {
detail::sync_request_bouncer f{self->exit_reason()}; detail::sync_request_bouncer f{self->exit_reason()};
f(hdr.sender, hdr.id); f(hdr.sender, hdr.id);
...@@ -115,15 +120,18 @@ class no_scheduling { ...@@ -115,15 +120,18 @@ class no_scheduling {
util::fiber fself; util::fiber fself;
auto rr = resumable::resume_later; auto rr = resumable::resume_later;
while (rr != resumable::done) { while (rr != resumable::done) {
std::cout << "before await_data\n";
await_data(self); await_data(self);
self->resume(&fself); std::cout << "before resume\n";
rr = self->resume(&fself);
std::cout << "after resume\n";
} }
}).detach(); }).detach();
} }
template<class Actor> template<class Actor>
void await_data(Actor* self) { void await_data(Actor* self) {
if (self->mailbox().empty()) { while (self->mailbox().empty()) {
lock_type guard(m_mtx); lock_type guard(m_mtx);
while (self->mailbox().empty()) m_cv.wait(guard); while (self->mailbox().empty()) m_cv.wait(guard);
} }
...@@ -132,7 +140,7 @@ class no_scheduling { ...@@ -132,7 +140,7 @@ class no_scheduling {
template<class Actor> template<class Actor>
bool await_data(Actor* self, const timeout_type& abs_time) { bool await_data(Actor* self, const timeout_type& abs_time) {
CPPA_REQUIRE(!self->mailbox().closed()); CPPA_REQUIRE(!self->mailbox().closed());
if (self->mailbox().empty()) { while (self->mailbox().empty()) {
lock_type guard(m_mtx); lock_type guard(m_mtx);
while (self->mailbox().empty()) { while (self->mailbox().empty()) {
if (m_cv.wait_until(guard, abs_time) == std::cv_status::timeout) { if (m_cv.wait_until(guard, abs_time) == std::cv_status::timeout) {
......
...@@ -46,8 +46,11 @@ struct not_prioritizing { ...@@ -46,8 +46,11 @@ struct not_prioritizing {
} }
template<class Actor, typename F> template<class Actor, typename F>
bool fetch_messages(Actor*, F) { bool fetch_messages(Actor* self, F cb) {
//FIXME auto fetch = [self] { return self->mailbox().try_pop(); };
for (auto e = fetch(); e != nullptr; e = fetch()) {
cb(e);
}
} }
}; };
......
...@@ -49,30 +49,25 @@ class sequential_invoke : public invoke_policy<sequential_invoke> { ...@@ -49,30 +49,25 @@ class sequential_invoke : public invoke_policy<sequential_invoke> {
sequential_invoke() : m_has_pending_tout(false), m_pending_tout(0) { } sequential_invoke() : m_has_pending_tout(false), m_pending_tout(0) { }
static inline bool hm_should_skip(pointer node) { static inline bool hm_should_skip(pointer) {
return node->marked; return false;
} }
template<class Actor> template<class Actor>
inline pointer hm_begin(Actor* self, pointer node) { static inline pointer hm_begin(Actor* self, pointer node) {
auto previous = self->m_current_node; auto previous = self->current_node();
self->m_current_node = node; self->current_node(node);
push_timeout();
node->marked = true;
return previous; return previous;
} }
template<class Actor> template<class Actor>
inline void hm_cleanup(Actor* self, pointer previous) { static inline void hm_cleanup(Actor* self, pointer) {
self->m_current_node->marked = false; self->current_node(&(self->m_dummy_node));
self->m_current_node = previous;
} }
template<class Actor> template<class Actor>
inline void hm_revert(Actor* self, pointer previous) { static inline void hm_revert(Actor* self, pointer previous) {
self->m_current_node->marked = false; self->current_node(previous);
self->m_current_node = previous;
pop_timeout();
} }
inline void reset_timeout() { inline void reset_timeout() {
......
...@@ -68,11 +68,14 @@ actor spawn(Ts&&... args) { ...@@ -68,11 +68,14 @@ actor spawn(Ts&&... args) {
"top-level spawns cannot have monitor or link flag"); "top-level spawns cannot have monitor or link flag");
static_assert(is_unbound(Options), static_assert(is_unbound(Options),
"top-level spawns cannot have monitor or link flag"); "top-level spawns cannot have monitor or link flag");
/*
using scheduling_policy = typename std::conditional< using scheduling_policy = typename std::conditional<
has_detach_flag(Options), has_detach_flag(Options),
policy::no_scheduling, policy::no_scheduling,
policy::cooperative_scheduling policy::cooperative_scheduling
>::type; >::type;
*/
using scheduling_policy = policy::no_scheduling;
using priority_policy = typename std::conditional< using priority_policy = typename std::conditional<
has_priority_aware_flag(Options), has_priority_aware_flag(Options),
policy::prioritizing, policy::prioritizing,
...@@ -100,19 +103,6 @@ actor spawn(Ts&&... args) { ...@@ -100,19 +103,6 @@ actor spawn(Ts&&... args) {
auto ptr = make_counted<proper_impl>(std::forward<Ts>(args)...); auto ptr = make_counted<proper_impl>(std::forward<Ts>(args)...);
ptr->launch(); ptr->launch();
return ptr; return ptr;
/*
scheduled_actor_ptr ptr;
if (has_priority_aware_flag(Options)) {
using derived = typename extend<Impl>::template with<threaded, prioritizing>;
ptr = make_counted<derived>(std::forward<Ts>(args)...);
}
else if (has_detach_flag(Options)) {
using derived = typename extend<Impl>::template with<threaded>;
ptr = make_counted<derived>(std::forward<Ts>(args)...);
}
else ptr = make_counted<Impl>(std::forward<Ts>(args)...);
return get_scheduler()->exec(Options, std::move(ptr));
*/
} }
/** /**
......
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
#include "cppa/config.hpp" #include "cppa/config.hpp"
#include "cppa/cppa.hpp" //#include "cppa/cppa.hpp"
#include "cppa/singletons.hpp" #include "cppa/singletons.hpp"
#include "cppa/util/scope_guard.hpp" #include "cppa/util/scope_guard.hpp"
...@@ -287,7 +287,6 @@ void broker::invoke_message(const message_header& hdr, any_tuple msg) { ...@@ -287,7 +287,6 @@ void broker::invoke_message(const message_header& hdr, any_tuple msg) {
m_dummy_node.msg = move(msg); m_dummy_node.msg = move(msg);
m_dummy_node.mid = hdr.id; m_dummy_node.mid = hdr.id;
try { try {
using detail::receive_policy;
auto bhvr = m_bhvr_stack.back(); auto bhvr = m_bhvr_stack.back();
switch (m_invoke.handle_message(this, switch (m_invoke.handle_message(this,
&m_dummy_node, &m_dummy_node,
......
...@@ -214,7 +214,6 @@ class local_group_proxy : public local_group { ...@@ -214,7 +214,6 @@ class local_group_proxy : public local_group {
: super(false, forward<Ts>(args)...) { : super(false, forward<Ts>(args)...) {
CPPA_REQUIRE(m_broker == nullptr); CPPA_REQUIRE(m_broker == nullptr);
CPPA_REQUIRE(remote_broker != nullptr); CPPA_REQUIRE(remote_broker != nullptr);
CPPA_REQUIRE(remote_broker->is_proxy());
m_broker = move(remote_broker); m_broker = move(remote_broker);
m_proxy_broker = spawn<proxy_broker, hidden>(this); m_proxy_broker = spawn<proxy_broker, hidden>(this);
} }
......
...@@ -148,12 +148,16 @@ response_handle local_actor::make_response_handle() { ...@@ -148,12 +148,16 @@ response_handle local_actor::make_response_handle() {
} }
*/ */
void local_actor::send_tuple(message_priority prio, const channel& dest, any_tuple what) {
dest.enqueue({address(), dest, prio}, std::move(what));
}
void local_actor::send_tuple(const channel& dest, any_tuple what) { void local_actor::send_tuple(const channel& dest, any_tuple what) {
//TODO: send_tuple(message_priority::normal, dest, std::move(what));
} }
void local_actor::send_exit(const actor_addr& whom, std::uint32_t reason) { void local_actor::send_exit(const actor_addr& whom, std::uint32_t reason) {
send(detail::raw_access::get(whom), atom("EXIT"), reason);
} }
void local_actor::remove_handler(message_id) { void local_actor::remove_handler(message_id) {
...@@ -170,16 +174,15 @@ message_future local_actor::timed_sync_send_tuple(const util::duration& rtime, ...@@ -170,16 +174,15 @@ message_future local_actor::timed_sync_send_tuple(const util::duration& rtime,
} }
void local_actor::send_tuple(message_priority prio, const channel& dest, any_tuple what) {
}
message_future local_actor::sync_send_tuple(const actor& dest, any_tuple what) { message_future local_actor::sync_send_tuple(const actor& dest, any_tuple what) {
} }
response_handle local_actor::make_response_handle() { response_handle local_actor::make_response_handle() {
return {}; auto n = m_current_node;
response_handle result{address(), n->sender, n->mid.response_id()};
n->mid.mark_as_answered();
return result;
} }
void local_actor::cleanup(std::uint32_t reason) { void local_actor::cleanup(std::uint32_t reason) {
......
...@@ -55,9 +55,11 @@ bool response_handle::synchronous() const { ...@@ -55,9 +55,11 @@ bool response_handle::synchronous() const {
} }
void response_handle::apply(any_tuple msg) const { void response_handle::apply(any_tuple msg) const {
std::cout << "response_handle::apply\n";
if (valid()) { if (valid()) {
auto ptr = detail::actor_addr_cast<abstract_actor>(m_to); auto ptr = detail::actor_addr_cast<abstract_actor>(m_to);
ptr->enqueue({m_from, ptr, m_id}, move(msg)); ptr->enqueue({m_from, ptr, m_id}, move(msg));
std::cout << "response_handle::apply: after ptr->enqueue\n";
} }
} }
......
...@@ -69,7 +69,6 @@ void publish(actor whom, std::unique_ptr<acceptor> aptr) { ...@@ -69,7 +69,6 @@ void publish(actor whom, std::unique_ptr<acceptor> aptr) {
CPPA_LOG_TRACE(CPPA_TARG(whom, to_string) << ", " << CPPA_MARG(ptr, get) CPPA_LOG_TRACE(CPPA_TARG(whom, to_string) << ", " << CPPA_MARG(ptr, get)
<< ", args.size() = " << args.size()); << ", args.size() = " << args.size());
if (!whom) return; if (!whom) return;
CPPA_REQUIRE(args.size() == 0);
get_actor_registry()->put(whom->id(), detail::actor_addr_cast<abstract_actor>(whom)); get_actor_registry()->put(whom->id(), detail::actor_addr_cast<abstract_actor>(whom));
auto mm = get_middleman(); auto mm = get_middleman();
mm->register_acceptor(whom, new peer_acceptor(mm, move(aptr), whom)); mm->register_acceptor(whom, new peer_acceptor(mm, move(aptr), whom));
...@@ -115,7 +114,7 @@ actor remote_actor(stream_ptr_pair io) { ...@@ -115,7 +114,7 @@ actor remote_actor(stream_ptr_pair io) {
CPPA_LOGF_DEBUG("result = " << result->value.get()); CPPA_LOGF_DEBUG("result = " << result->value.get());
return result->value; return result->value;
} }
actor remote_actor(const char* host, std::uint16_t port) { actor remote_actor(const char* host, std::uint16_t port) {
auto io = ipv4_io_stream::connect_to(host, port); auto io = ipv4_io_stream::connect_to(host, port);
return remote_actor(stream_ptr_pair(io, io)); return remote_actor(stream_ptr_pair(io, io));
......
...@@ -58,18 +58,17 @@ namespace cppa { namespace detail { ...@@ -58,18 +58,17 @@ namespace cppa { namespace detail {
// maps demangled names to libcppa names // maps demangled names to libcppa names
// WARNING: this map is sorted, insert new elements *in sorted order* as well! // WARNING: this map is sorted, insert new elements *in sorted order* as well!
/* extern */ const char* mapped_type_names[][2] = { /* extern */ const char* mapped_type_names[][2] = {
{ "bool", "bool" },
{ "cppa::actor", "@actor" }, { "cppa::actor", "@actor" },
{ "cppa::actor_addr", "@addr" }, { "cppa::actor_addr", "@addr" },
{ "bool", "bool" },
{ "cppa::any_tuple", "@tuple" }, { "cppa::any_tuple", "@tuple" },
{ "cppa::atom_value", "@atom" }, { "cppa::atom_value", "@atom" },
{ "cppa::intrusive_ptr<cppa::channel>", "@channel" }, { "cppa::channel", "@channel" },
{ "cppa::intrusive_ptr<cppa::group>", "@group" }, { "cppa::intrusive_ptr<cppa::group>", "@group" },
{ "cppa::intrusive_ptr<cppa::node_id>", "@proc" }, { "cppa::intrusive_ptr<cppa::node_id>", "@proc" },
{ "cppa::io::accept_handle", "@ac_hdl" }, { "cppa::io::accept_handle", "@ac_hdl" },
{ "cppa::io::connection_handle", "@cn_hdl" }, { "cppa::io::connection_handle", "@cn_hdl" },
{ "cppa::message_header", "@header" }, { "cppa::message_header", "@header" },
{ "cppa::nullptr_t", "@null" },
{ "cppa::unit_t", "@0" }, { "cppa::unit_t", "@0" },
{ "cppa::util::buffer", "@buffer" }, { "cppa::util::buffer", "@buffer" },
{ "cppa::util::duration", "@duration" }, { "cppa::util::duration", "@duration" },
......
...@@ -458,6 +458,24 @@ void test_continuation() { ...@@ -458,6 +458,24 @@ void test_continuation() {
void test_spawn() { void test_spawn() {
scoped_actor self; scoped_actor self;
auto s = spawn([](untyped_actor* self) -> behavior {
return (
others() >> [=]() -> any_tuple {
cout << "received: " << to_string(self->last_dequeued()) << endl;
return self->last_dequeued();
}
);
});
cout << "spawned actor, waiting for response" << endl;
self->send(s, atom("hello"));
self->receive(
others() >> [&] {
cout << "received: " << to_string(self->last_dequeued()) << endl;
}
);
self->await_all_other_actors_done();
return;
test_serial_reply(); test_serial_reply();
test_or_else(); test_or_else();
test_continuation(); test_continuation();
......
...@@ -102,7 +102,7 @@ struct C : sb_actor<C> { ...@@ -102,7 +102,7 @@ struct C : sb_actor<C> {
struct D : popular_actor { struct D : popular_actor {
D(const actor& buddy) : popular_actor(buddy) { } D(const actor& buddy) : popular_actor(buddy) { }
behavior make_behavior() override { behavior make_behavior() override {
become ( return (
others() >> [=] { others() >> [=] {
/* /*
response_handle handle = make_response_handle(); response_handle handle = make_response_handle();
...@@ -140,7 +140,7 @@ struct server : untyped_actor { ...@@ -140,7 +140,7 @@ struct server : untyped_actor {
behavior make_behavior() override { behavior make_behavior() override {
auto die = [=] { quit(exit_reason::user_shutdown); }; auto die = [=] { quit(exit_reason::user_shutdown); };
become ( return (
on(atom("idle"), arg_match) >> [=](actor worker) { on(atom("idle"), arg_match) >> [=](actor worker) {
become ( become (
keep_behavior, keep_behavior,
......
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