Commit 48a29c72 authored by Dominik Charousset's avatar Dominik Charousset

maintenance & documentation update

this patch renames `message_id_t` to `message_id`,
condenses the `receive` functions, and updates the documentation
parent ef0b744f
...@@ -137,7 +137,6 @@ set(LIBCPPA_SRC ...@@ -137,7 +137,6 @@ set(LIBCPPA_SRC
src/primitive_variant.cpp src/primitive_variant.cpp
src/process_information.cpp src/process_information.cpp
src/protocol.cpp src/protocol.cpp
src/receive.cpp
src/recursive_queue_node.cpp src/recursive_queue_node.cpp
src/ref_counted.cpp src/ref_counted.cpp
src/response_handle.cpp src/response_handle.cpp
......
...@@ -80,7 +80,6 @@ cppa/group.hpp ...@@ -80,7 +80,6 @@ cppa/group.hpp
cppa/guard_expr.hpp cppa/guard_expr.hpp
cppa/intrusive/blocking_single_reader_queue.hpp cppa/intrusive/blocking_single_reader_queue.hpp
cppa/intrusive/single_reader_queue.hpp cppa/intrusive/single_reader_queue.hpp
cppa/intrusive_fwd_ptr.hpp
cppa/intrusive_ptr.hpp cppa/intrusive_ptr.hpp
cppa/local_actor.hpp cppa/local_actor.hpp
cppa/logging.hpp cppa/logging.hpp
...@@ -244,7 +243,6 @@ src/partial_function.cpp ...@@ -244,7 +243,6 @@ src/partial_function.cpp
src/primitive_variant.cpp src/primitive_variant.cpp
src/process_information.cpp src/process_information.cpp
src/protocol.cpp src/protocol.cpp
src/receive.cpp
src/recursive_queue_node.cpp src/recursive_queue_node.cpp
src/ref_counted.cpp src/ref_counted.cpp
src/response_handle.cpp src/response_handle.cpp
......
...@@ -86,7 +86,7 @@ class actor : public channel { ...@@ -86,7 +86,7 @@ class actor : public channel {
* @pre <tt>id.valid()</tt> * @pre <tt>id.valid()</tt>
*/ */
virtual void sync_enqueue(const actor_ptr& sender, virtual void sync_enqueue(const actor_ptr& sender,
message_id_t id, message_id id,
any_tuple msg) = 0; any_tuple msg) = 0;
/** /**
...@@ -96,7 +96,7 @@ class actor : public channel { ...@@ -96,7 +96,7 @@ class actor : public channel {
* its state to @p pending in response to the enqueue operation. * its state to @p pending in response to the enqueue operation.
*/ */
virtual bool chained_sync_enqueue(const actor_ptr& sender, virtual bool chained_sync_enqueue(const actor_ptr& sender,
message_id_t id, message_id id,
any_tuple msg); any_tuple msg);
/** /**
......
...@@ -135,7 +135,7 @@ class actor_companion_mixin : public Base { ...@@ -135,7 +135,7 @@ class actor_companion_mixin : public Base {
} }
void sync_enqueue(const actor_ptr& sender, void sync_enqueue(const actor_ptr& sender,
message_id_t id, message_id id,
any_tuple msg) { any_tuple msg) {
util::shared_lock_guard<lock_type> guard(m_lock); util::shared_lock_guard<lock_type> guard(m_lock);
if (m_parent) { if (m_parent) {
...@@ -151,15 +151,15 @@ class actor_companion_mixin : public Base { ...@@ -151,15 +151,15 @@ class actor_companion_mixin : public Base {
"management instead!"); "management instead!");
} }
void dequeue(behavior&) { throw_no_recv(); } void dequeue(behavior&) {
throw_no_recv();
void dequeue(partial_function&) { throw_no_recv(); } }
void dequeue_response(behavior&, message_id_t) { void dequeue_response(behavior&, message_id) {
throw_no_recv(); throw_no_recv();
} }
void become_waiting_for(behavior&&, message_id_t) { void become_waiting_for(behavior, message_id) {
throw_no_become(); throw_no_become();
} }
......
...@@ -56,10 +56,18 @@ class behavior { ...@@ -56,10 +56,18 @@ class behavior {
public: public:
/** @cond PRIVATE */
typedef intrusive_ptr<detail::behavior_impl> impl_ptr; typedef intrusive_ptr<detail::behavior_impl> impl_ptr;
inline auto as_behavior_impl() const -> const impl_ptr&;
inline behavior(impl_ptr ptr);
static constexpr bool may_have_timeout = true; static constexpr bool may_have_timeout = true;
/** @endcond */
behavior() = default; behavior() = default;
behavior(behavior&&) = default; behavior(behavior&&) = default;
behavior(const behavior&) = default; behavior(const behavior&) = default;
...@@ -68,49 +76,39 @@ class behavior { ...@@ -68,49 +76,39 @@ class behavior {
behavior(const partial_function& fun); behavior(const partial_function& fun);
inline behavior(impl_ptr ptr) : m_impl(std::move(ptr)) { }
template<typename F> template<typename F>
behavior(const timeout_definition<F>& arg) behavior(const timeout_definition<F>& arg);
: m_impl(detail::new_default_behavior_impl(detail::dummy_match_expr{},
arg.timeout,
arg.handler) ) { }
template<typename F> template<typename F>
behavior(util::duration d, F f) behavior(util::duration d, F f);
: m_impl(detail::new_default_behavior_impl(detail::dummy_match_expr{}, d, f)) { }
template<typename... Cases>
behavior(const match_expr<Cases...>& arg0)
: m_impl(detail::new_default_behavior_impl(arg0, util::duration(), []() { })) { }
template<typename... Cases, typename Arg1, typename... Args> template<typename... Cases, typename... Ts>
behavior(const match_expr<Cases...>& arg0, const Arg1& arg1, const Args&... args) behavior(const match_expr<Cases...>& arg, const Ts&... args);
: m_impl(detail::match_expr_concat(arg0, arg1, args...)) { }
inline void handle_timeout() { /**
m_impl->handle_timeout(); * @brief Invokes the timeout callback.
} */
inline void handle_timeout();
inline const util::duration& timeout() const {
return m_impl->timeout();
}
inline bool undefined() const { /**
return m_impl == nullptr || m_impl->timeout().valid() == false; * @brief Returns the duration after which receives using
} * this behavior should time out.
*/
inline const util::duration& timeout() const;
/**
* @copydoc partial_function::operator()()
*/
template<typename T> template<typename T>
inline bool operator()(T&& arg) { inline bool operator()(T&& arg);
return (m_impl) && m_impl->invoke(std::forward<T>(arg));
}
/**
* @brief Adds a continuation to this behavior that is executed
* whenever this behavior was successfully applied to
* a message.
*/
template<typename F> template<typename F>
inline behavior add_continuation(F fun) { inline behavior add_continuation(F fun);
return {new detail::continuation_decorator<F>(std::move(fun), m_impl)};
}
const impl_ptr& as_behavior_impl() const { return m_impl; }
private: private:
...@@ -118,12 +116,60 @@ class behavior { ...@@ -118,12 +116,60 @@ class behavior {
}; };
template<typename... Lhs, typename F> /**
inline behavior operator,(const match_expr<Lhs...>& lhs, * @brief Creates a behavior from a match expression and a timeout definition.
* @relates behavior
*/
template<typename... Cases, typename F>
inline behavior operator,(const match_expr<Cases...>& lhs,
const timeout_definition<F>& rhs) { const timeout_definition<F>& rhs) {
return match_expr_convert(lhs, rhs); return match_expr_convert(lhs, rhs);
} }
/******************************************************************************
* inline and template member function implementations *
******************************************************************************/
template<typename F>
behavior::behavior(const timeout_definition<F>& arg)
: m_impl(detail::new_default_behavior_impl(detail::dummy_match_expr{},
arg.timeout,
arg.handler) ) { }
template<typename F>
behavior::behavior(util::duration d, F f)
: m_impl(detail::new_default_behavior_impl(detail::dummy_match_expr{}, d, f)) { }
template<typename... Cases, typename... Ts>
behavior::behavior(const match_expr<Cases...>& arg, const Ts&... args)
: m_impl(detail::match_expr_concat(arg, args...)) { }
inline behavior::behavior(impl_ptr ptr) : m_impl(std::move(ptr)) { }
inline void behavior::handle_timeout() {
m_impl->handle_timeout();
}
inline const util::duration& behavior::timeout() const {
return m_impl->timeout();
}
template<typename T>
inline bool behavior::operator()(T&& arg) {
return (m_impl) && m_impl->invoke(std::forward<T>(arg));
}
inline auto behavior::as_behavior_impl() const -> const impl_ptr& {
return m_impl;
}
template<typename F>
inline behavior behavior::add_continuation(F fun) {
return {new detail::continuation_decorator<F>(std::move(fun), m_impl)};
}
} // namespace cppa } // namespace cppa
#endif // CPPA_BEHAVIOR_HPP #endif // CPPA_BEHAVIOR_HPP
...@@ -67,12 +67,6 @@ class channel : public ref_counted { ...@@ -67,12 +67,6 @@ class channel : public ref_counted {
virtual ~channel(); virtual ~channel();
private:
// channel is a sealed class and the only
// allowed subclasses are actor and group.
channel() = default;
}; };
/** /**
...@@ -84,8 +78,8 @@ typedef intrusive_ptr<channel> channel_ptr; ...@@ -84,8 +78,8 @@ typedef intrusive_ptr<channel> channel_ptr;
/** /**
* @brief Convenience alias. * @brief Convenience alias.
*/ */
template<typename T> template<typename T, typename R = void>
using enable_if_channel = std::enable_if<std::is_base_of<channel,T>::value>; using enable_if_channel = std::enable_if<std::is_base_of<channel,T>::value,R>;
} // namespace cppa } // namespace cppa
......
...@@ -191,11 +191,20 @@ ...@@ -191,11 +191,20 @@
* *
* @defgroup MessageHandling Message handling. * @defgroup MessageHandling Message handling.
* *
* This is the beating heart of @p libcppa. Actor programming is all about * @brief This is the beating heart of @p libcppa. Actor programming is
* message handling. * all about message handling.
* *
* A message in @p libcppa is a n-tuple of values (with size >= 1). You can use * A message in @p libcppa is a n-tuple of values (with size >= 1). You can use
* almost every type in a messages. * almost every type in a messages - as long as it is announced, i.e., known
* by libcppa's type system.
*
* @defgroup BlockingAPI Blocking API.
*
* @brief Blocking functions to receive messages.
*
* The blocking API of libcppa is intended to be used for migrating
* previously threaded applications. When writing new code, you should use
* ibcppas nonblocking become/unbecome API.
* *
* @section Send Send messages * @section Send Send messages
* *
...@@ -414,15 +423,14 @@ namespace cppa { ...@@ -414,15 +423,14 @@ namespace cppa {
namespace detail { namespace detail {
template<typename T> template<typename T>
inline void send_impl(T* whom, any_tuple&& what) { inline void send_impl(T* ptr, any_tuple&& arg) {
if (whom) self->send_message(whom, std::move(what)); if (ptr) self->send_message(ptr, std::move(arg));
} }
template<typename T, typename... Ts> template<typename T, typename... Ts>
inline void send_tpl_impl(T* whom, Ts&&... what) { inline void send_tpl_impl(T* ptr, Ts&&... args) {
static_assert(sizeof...(Ts) > 0, "no message to send"); static_assert(sizeof...(Ts) > 0, "no message to send");
if (whom) self->send_message(whom, if (ptr) self->send_message(ptr, make_any_tuple(std::forward<Ts>(args)...));
make_any_tuple(std::forward<Ts>(what)...));
} }
} // namespace detail } // namespace detail
...@@ -438,7 +446,7 @@ inline void send_tpl_impl(T* whom, Ts&&... what) { ...@@ -438,7 +446,7 @@ inline void send_tpl_impl(T* whom, Ts&&... what) {
* @param what Message content as tuple. * @param what Message content as tuple.
*/ */
template<class C, typename... Ts> template<class C, typename... Ts>
inline typename std::enable_if<std::is_base_of<channel, C>::value>::type inline typename enable_if_channel<C>::type
send_tuple(const intrusive_ptr<C>& whom, any_tuple what) { send_tuple(const intrusive_ptr<C>& whom, any_tuple what) {
detail::send_impl(whom.get(), std::move(what)); detail::send_impl(whom.get(), std::move(what));
} }
...@@ -450,9 +458,9 @@ send_tuple(const intrusive_ptr<C>& whom, any_tuple what) { ...@@ -450,9 +458,9 @@ send_tuple(const intrusive_ptr<C>& whom, any_tuple what) {
* @pre <tt>sizeof...(Ts) > 0</tt> * @pre <tt>sizeof...(Ts) > 0</tt>
*/ */
template<class C, typename... Ts> template<class C, typename... Ts>
inline typename std::enable_if<std::is_base_of<channel, C>::value>::type inline typename enable_if_channel<C>::type
send(const intrusive_ptr<C>& whom, Ts&&... what) { send(const intrusive_ptr<C>& whom, Ts&&... args) {
detail::send_tpl_impl(whom.get(), std::forward<Ts>(what)...); detail::send_tpl_impl(whom.get(), std::forward<Ts>(args)...);
} }
/** /**
...@@ -464,7 +472,7 @@ send(const intrusive_ptr<C>& whom, Ts&&... what) { ...@@ -464,7 +472,7 @@ send(const intrusive_ptr<C>& whom, Ts&&... what) {
* @pre <tt>sizeof...(Ts) > 0</tt> * @pre <tt>sizeof...(Ts) > 0</tt>
*/ */
template<class C, typename... Ts> template<class C, typename... Ts>
inline typename std::enable_if<std::is_base_of<channel, C>::value>::type inline typename enable_if_channel<C>::type
send_tuple_as(const actor_ptr& from, const intrusive_ptr<C>& whom, any_tuple what) { send_tuple_as(const actor_ptr& from, const intrusive_ptr<C>& whom, any_tuple what) {
if (whom) whom->enqueue(from.get(), std::move(what)); if (whom) whom->enqueue(from.get(), std::move(what));
} }
...@@ -478,7 +486,7 @@ send_tuple_as(const actor_ptr& from, const intrusive_ptr<C>& whom, any_tuple wha ...@@ -478,7 +486,7 @@ send_tuple_as(const actor_ptr& from, const intrusive_ptr<C>& whom, any_tuple wha
* @pre <tt>sizeof...(Ts) > 0</tt> * @pre <tt>sizeof...(Ts) > 0</tt>
*/ */
template<class C, typename... Ts> template<class C, typename... Ts>
inline typename std::enable_if<std::is_base_of<channel, C>::value>::type inline typename enable_if_channel<C>::type
send_as(const actor_ptr& from, const intrusive_ptr<C>& whom, Ts&&... what) { send_as(const actor_ptr& from, const intrusive_ptr<C>& whom, Ts&&... what) {
send_tuple_as(from, whom, make_any_tuple(std::forward<Ts>(what)...)); send_tuple_as(from, whom, make_any_tuple(std::forward<Ts>(what)...));
} }
...@@ -495,8 +503,7 @@ send_as(const actor_ptr& from, const intrusive_ptr<C>& whom, Ts&&... what) { ...@@ -495,8 +503,7 @@ send_as(const actor_ptr& from, const intrusive_ptr<C>& whom, Ts&&... what) {
* @returns @p whom. * @returns @p whom.
*/ */
template<class C> template<class C>
inline typename std::enable_if<std::is_base_of<channel, C>::value, inline typename enable_if_channel<C,const intrusive_ptr<C>&>::type
const intrusive_ptr<C>& >::type
operator<<(const intrusive_ptr<C>& whom, any_tuple what) { operator<<(const intrusive_ptr<C>& whom, any_tuple what) {
send_tuple(whom, std::move(what)); send_tuple(whom, std::move(what));
return whom; return whom;
...@@ -683,18 +690,20 @@ inline void delayed_reply(const std::chrono::duration<Rep, Period>& rtime, ...@@ -683,18 +690,20 @@ inline void delayed_reply(const std::chrono::duration<Rep, Period>& rtime,
delayed_reply_tuple(rtime, make_any_tuple(std::forward<Ts>(what)...)); delayed_reply_tuple(rtime, make_any_tuple(std::forward<Ts>(what)...));
} }
/** @} */ /**
* @}
*/
// matches "send(this, ...)" and "send(self, ...)" // matches "send(this, ...)" and "send(self, ...)"
inline void send_tuple(local_actor* whom, any_tuple what) { inline void send_tuple(channel* whom, any_tuple what) {
detail::send_impl(whom, std::move(what)); detail::send_impl(whom, std::move(what));
} }
template<typename... Ts> template<typename... Ts>
inline void send(local_actor* whom, Ts&&... args) { inline void send(channel* whom, Ts&&... args) {
detail::send_tpl_impl(whom, std::forward<Ts>(args)...); detail::send_tpl_impl(whom, std::forward<Ts>(args)...);
} }
inline const self_type& operator<<(const self_type& s, any_tuple what) { inline const self_type& operator<<(const self_type& s, any_tuple what) {
detail::send_impl(s.get(), std::move(what)); detail::send_impl(static_cast<channel*>(s.get()), std::move(what));
return s; return s;
} }
inline actor_ptr eval_sopts(spawn_options opts, actor_ptr ptr) { inline actor_ptr eval_sopts(spawn_options opts, actor_ptr ptr) {
...@@ -844,15 +853,24 @@ void shutdown(); // note: implemented in singleton_manager.cpp ...@@ -844,15 +853,24 @@ void shutdown(); // note: implemented in singleton_manager.cpp
*/ */
inline void quit_actor(const actor_ptr& whom, std::uint32_t reason) { inline void quit_actor(const actor_ptr& whom, std::uint32_t reason) {
CPPA_REQUIRE(reason != exit_reason::normal); CPPA_REQUIRE(reason != exit_reason::normal);
send(whom, atom("EXIT"), reason); send(whom.get(), atom("EXIT"), reason);
} }
/**
* @brief Sets the actor's behavior and discards the previous behavior
* unless {@link keep_behavior} is given as first argument.
*/
template<typename... Ts> template<typename... Ts>
inline void become(Ts&&... args) { inline void become(Ts&&... args) {
self->become(std::forward<Ts>(args)...); self->become(std::forward<Ts>(args)...);
} }
inline void unbecome() { self->unbecome(); } /**
* @brief Returns to a previous behavior if available.
*/
inline void unbecome() {
self->unbecome();
}
struct actor_ostream { struct actor_ostream {
...@@ -883,9 +901,11 @@ inline const actor_ostream& operator<<(const actor_ostream& o, const any_tuple& ...@@ -883,9 +901,11 @@ inline const actor_ostream& operator<<(const actor_ostream& o, const any_tuple&
} }
template<typename T> template<typename T>
inline typename std::enable_if< !std::is_convertible<T,std::string>::value inline typename std::enable_if<
!std::is_convertible<T,std::string>::value
&& !std::is_convertible<T,any_tuple>::value, && !std::is_convertible<T,any_tuple>::value,
const actor_ostream&>::type const actor_ostream&
>::type
operator<<(const actor_ostream& o, T&& arg) { operator<<(const actor_ostream& o, T&& arg) {
return o.write(std::to_string(std::forward<T>(arg))); return o.write(std::to_string(std::forward<T>(arg)));
} }
......
...@@ -54,14 +54,14 @@ class behavior_stack ...@@ -54,14 +54,14 @@ class behavior_stack
behavior_stack(const behavior_stack&) = delete; behavior_stack(const behavior_stack&) = delete;
behavior_stack& operator=(const behavior_stack&) = delete; behavior_stack& operator=(const behavior_stack&) = delete;
typedef std::pair<behavior,message_id_t> element_type; typedef std::pair<behavior,message_id> element_type;
public: public:
behavior_stack() = default; behavior_stack() = default;
// @pre expected_response.valid() // @pre expected_response.valid()
option<behavior&> sync_handler(message_id_t expected_response); option<behavior&> sync_handler(message_id expected_response);
// erases the last asynchronous message handler // erases the last asynchronous message handler
void pop_async_back(); void pop_async_back();
...@@ -69,7 +69,7 @@ class behavior_stack ...@@ -69,7 +69,7 @@ class behavior_stack
void clear(); void clear();
// erases the synchronous response handler associated with @p rid // erases the synchronous response handler associated with @p rid
void erase(message_id_t rid) { void erase(message_id rid) {
erase_if([=](const element_type& e) { return e.second == rid; }); erase_if([=](const element_type& e) { return e.second == rid; });
} }
...@@ -81,7 +81,7 @@ class behavior_stack ...@@ -81,7 +81,7 @@ class behavior_stack
} }
inline void push_back(behavior&& what, inline void push_back(behavior&& what,
message_id_t response_id = message_id_t::invalid) { message_id response_id = message_id::invalid) {
m_elements.emplace_back(std::move(what), response_id); m_elements.emplace_back(std::move(what), response_id);
} }
......
...@@ -51,24 +51,15 @@ struct receive_while_helper { ...@@ -51,24 +51,15 @@ struct receive_while_helper {
template<typename S> template<typename S>
receive_while_helper(S&& stmt) : m_stmt(std::forward<S>(stmt)) { } receive_while_helper(S&& stmt) : m_stmt(std::forward<S>(stmt)) { }
void operator()(behavior& bhvr) { template<typename... Ts>
void operator()(Ts&&... args) {
static_assert(sizeof...(Ts) > 0,
"operator() requires at least one argument");
behavior tmp = match_expr_convert(std::forward<Ts>(args)...);
local_actor* sptr = self; local_actor* sptr = self;
while (m_stmt()) sptr->dequeue(bhvr); while (m_stmt()) sptr->dequeue(tmp);
} }
void operator()(partial_function& fun) {
local_actor* sptr = self;
while (m_stmt()) sptr->dequeue(fun);
}
template<typename Arg0, typename... Args>
void operator()(Arg0&& arg0, Args&&... args) {
auto tmp = match_expr_convert(std::forward<Arg0>(arg0),
std::forward<Args>(args)...);
(*this)(tmp);
}
}; };
template<typename T> template<typename T>
...@@ -81,21 +72,11 @@ class receive_for_helper { ...@@ -81,21 +72,11 @@ class receive_for_helper {
receive_for_helper(T& first, const T& last) : begin(first), end(last) { } receive_for_helper(T& first, const T& last) : begin(first), end(last) { }
void operator()(behavior& bhvr) { template<typename... Ts>
void operator()(Ts&&... args) {
auto tmp = match_expr_convert(std::forward<Ts>(args)...);
local_actor* sptr = self; local_actor* sptr = self;
for ( ; begin != end; ++begin) sptr->dequeue(bhvr); for ( ; begin != end; ++begin) sptr->dequeue(tmp);
}
void operator()(partial_function& fun) {
local_actor* sptr = self;
for ( ; begin != end; ++begin) sptr->dequeue(fun);
}
template<typename Arg0, typename... Args>
void operator()(Arg0&& arg0, Args&&... args) {
auto tmp = match_expr_convert(std::forward<Arg0>(arg0),
std::forward<Args>(args)...);
(*this)(tmp);
} }
}; };
...@@ -106,10 +87,7 @@ class do_receive_helper { ...@@ -106,10 +87,7 @@ class do_receive_helper {
public: public:
template<typename... Args> inline do_receive_helper(behavior&& bhvr) : m_bhvr(std::move(bhvr)) { }
do_receive_helper(Args&&... args)
: m_bhvr(match_expr_convert(std::forward<Args>(args)...)) {
}
do_receive_helper(do_receive_helper&&) = default; do_receive_helper(do_receive_helper&&) = default;
......
...@@ -76,7 +76,7 @@ class receive_policy { ...@@ -76,7 +76,7 @@ class receive_policy {
template<class Client, class Fun> template<class Client, class Fun>
bool invoke_from_cache(Client* client, bool invoke_from_cache(Client* client,
Fun& fun, Fun& fun,
message_id_t awaited_response = message_id_t()) { message_id awaited_response = message_id{}) {
std::integral_constant<receive_policy_flag,Client::receive_flag> policy; std::integral_constant<receive_policy_flag,Client::receive_flag> policy;
auto i = m_cache.begin(); auto i = m_cache.begin();
auto e = m_cache.end(); auto e = m_cache.end();
...@@ -108,7 +108,7 @@ class receive_policy { ...@@ -108,7 +108,7 @@ class receive_policy {
bool invoke(Client* client, bool invoke(Client* client,
pointer node_ptr, pointer node_ptr,
Fun& fun, Fun& fun,
message_id_t awaited_response = message_id_t()) { message_id awaited_response = message_id()) {
smart_pointer node(node_ptr); smart_pointer node(node_ptr);
std::integral_constant<receive_policy_flag,Client::receive_flag> policy; std::integral_constant<receive_policy_flag,Client::receive_flag> policy;
switch (this->handle_message(client, node.get(), fun, switch (this->handle_message(client, node.get(), fun,
...@@ -176,7 +176,7 @@ class receive_policy { ...@@ -176,7 +176,7 @@ class receive_policy {
} }
template<class Client> template<class Client>
void receive(Client* client, behavior& bhvr, message_id_t mid) { void receive(Client* client, behavior& bhvr, message_id mid) {
CPPA_REQUIRE(mid.is_response()); CPPA_REQUIRE(mid.is_response());
if (!invoke_from_cache(client, bhvr, mid)) { if (!invoke_from_cache(client, bhvr, mid)) {
if (bhvr.timeout().valid()) { if (bhvr.timeout().valid()) {
...@@ -231,7 +231,7 @@ class receive_policy { ...@@ -231,7 +231,7 @@ class receive_policy {
template<class Client> template<class Client>
filter_result filter_msg(Client* client, pointer node) { filter_result filter_msg(Client* client, pointer node) {
const any_tuple& msg = node->msg; const any_tuple& msg = node->msg;
auto message_id = node->mid; auto mid = node->mid;
auto& arr = detail::static_types_array<atom_value,std::uint32_t>::arr; auto& arr = detail::static_types_array<atom_value,std::uint32_t>::arr;
if ( msg.size() == 2 if ( msg.size() == 2
&& msg.type_at(0) == arr[0] && msg.type_at(0) == arr[0]
...@@ -239,7 +239,7 @@ class receive_policy { ...@@ -239,7 +239,7 @@ class receive_policy {
auto v0 = msg.get_as<atom_value>(0); auto v0 = msg.get_as<atom_value>(0);
auto v1 = msg.get_as<std::uint32_t>(1); auto v1 = msg.get_as<std::uint32_t>(1);
if (v0 == atom("EXIT")) { if (v0 == atom("EXIT")) {
CPPA_REQUIRE(!message_id.valid()); CPPA_REQUIRE(!mid.valid());
if (client->m_trap_exit == false) { if (client->m_trap_exit == false) {
if (v1 != exit_reason::normal) { if (v1 != exit_reason::normal) {
client->quit(v1); client->quit(v1);
...@@ -249,7 +249,7 @@ class receive_policy { ...@@ -249,7 +249,7 @@ class receive_policy {
} }
} }
else if (v0 == atom("SYNC_TOUT")) { else if (v0 == atom("SYNC_TOUT")) {
CPPA_REQUIRE(!message_id.valid()); CPPA_REQUIRE(!mid.valid());
return client->waits_for_timeout(v1) ? timeout_message return client->waits_for_timeout(v1) ? timeout_message
: expired_timeout_message; : expired_timeout_message;
} }
...@@ -257,11 +257,11 @@ class receive_policy { ...@@ -257,11 +257,11 @@ class receive_policy {
else if ( msg.size() == 1 else if ( msg.size() == 1
&& msg.type_at(0) == arr[0] && msg.type_at(0) == arr[0]
&& msg.get_as<atom_value>(0) == atom("TIMEOUT") && msg.get_as<atom_value>(0) == atom("TIMEOUT")
&& message_id.is_response()) { && mid.is_response()) {
return timeout_response_message; return timeout_response_message;
} }
if (message_id.is_response()) { if (mid.is_response()) {
return (client->awaits(message_id)) ? sync_response return (client->awaits(mid)) ? sync_response
: expired_sync_response; : expired_sync_response;
} }
return ordinary_message; return ordinary_message;
...@@ -340,7 +340,7 @@ class receive_policy { ...@@ -340,7 +340,7 @@ class receive_policy {
handle_message_result handle_message(Client* client, handle_message_result handle_message(Client* client,
pointer node, pointer node,
Fun& fun, Fun& fun,
message_id_t awaited_response, message_id awaited_response,
Policy policy ) { Policy policy ) {
bool handle_sync_failure_on_mismatch = true; bool handle_sync_failure_on_mismatch = true;
if (hm_should_skip(node, policy)) { if (hm_should_skip(node, policy)) {
......
...@@ -57,7 +57,7 @@ class recursive_queue_node : public memory_cached<memory_managed,recursive_queue ...@@ -57,7 +57,7 @@ class recursive_queue_node : public memory_cached<memory_managed,recursive_queue
bool marked; // denotes if this node is currently processed bool marked; // denotes if this node is currently processed
actor_ptr sender; // points to the sender of msg actor_ptr sender; // points to the sender of msg
any_tuple msg; // 'content field' any_tuple msg; // 'content field'
message_id_t mid; message_id mid;
recursive_queue_node(recursive_queue_node&&) = delete; recursive_queue_node(recursive_queue_node&&) = delete;
recursive_queue_node(const recursive_queue_node&) = delete; recursive_queue_node(const recursive_queue_node&) = delete;
...@@ -75,7 +75,7 @@ class recursive_queue_node : public memory_cached<memory_managed,recursive_queue ...@@ -75,7 +75,7 @@ class recursive_queue_node : public memory_cached<memory_managed,recursive_queue
recursive_queue_node(const actor_ptr& sptr, recursive_queue_node(const actor_ptr& sptr,
any_tuple data, any_tuple data,
message_id_t id = message_id_t{}); message_id id = message_id{});
}; };
......
...@@ -38,14 +38,13 @@ namespace cppa { namespace detail { ...@@ -38,14 +38,13 @@ namespace cppa { namespace detail {
struct scheduled_actor_dummy : scheduled_actor { struct scheduled_actor_dummy : scheduled_actor {
scheduled_actor_dummy(); scheduled_actor_dummy();
void enqueue(const actor_ptr&, any_tuple); void enqueue(const actor_ptr&, any_tuple);
void sync_enqueue(const actor_ptr&, message_id_t, any_tuple); void sync_enqueue(const actor_ptr&, message_id, any_tuple);
resume_result resume(util::fiber*, actor_ptr&); resume_result resume(util::fiber*, actor_ptr&);
void quit(std::uint32_t); void quit(std::uint32_t);
void dequeue(behavior&); void dequeue(behavior&);
void dequeue(partial_function&); void dequeue_response(behavior&, message_id);
void dequeue_response(behavior&, message_id_t);
void do_become(behavior&&, bool); void do_become(behavior&&, bool);
void become_waiting_for(behavior&&, message_id_t); void become_waiting_for(behavior, message_id);
bool has_behavior(); bool has_behavior();
scheduled_actor_type impl_type(); scheduled_actor_type impl_type();
}; };
......
...@@ -45,7 +45,7 @@ struct sync_request_bouncer { ...@@ -45,7 +45,7 @@ struct sync_request_bouncer {
std::uint32_t rsn; std::uint32_t rsn;
constexpr sync_request_bouncer(std::uint32_t r) constexpr sync_request_bouncer(std::uint32_t r)
: rsn(r == exit_reason::not_exited ? exit_reason::normal : r) { } : rsn(r == exit_reason::not_exited ? exit_reason::normal : r) { }
inline void operator()(const actor_ptr& sender, const message_id_t& 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; actor_ptr nobody;
......
...@@ -65,12 +65,7 @@ class event_based_actor : public scheduled_actor { ...@@ -65,12 +65,7 @@ class event_based_actor : public scheduled_actor {
/** /**
* @copydoc dequeue(behavior&) * @copydoc dequeue(behavior&)
*/ */
void dequeue(partial_function&); //override void dequeue_response(behavior&, message_id);
/**
* @copydoc dequeue(behavior&)
*/
void dequeue_response(behavior&, message_id_t);
resume_result resume(util::fiber*, actor_ptr&); //override resume_result resume(util::fiber*, actor_ptr&); //override
...@@ -130,7 +125,7 @@ class event_based_actor : public scheduled_actor { ...@@ -130,7 +125,7 @@ class event_based_actor : public scheduled_actor {
void do_become(behavior&& bhvr, bool discard_old); void do_become(behavior&& bhvr, bool discard_old);
void become_waiting_for(behavior&& bhvr, message_id_t mf); void become_waiting_for(behavior bhvr, message_id mf);
private: private:
......
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_ *
* /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\ *
* \/____/ \/_/\/___/ \/____/ \ \ \/ \ \ \/ \/__/\/_/ *
* \ \_\ \ \_\ *
* \/_/ \/_/ *
* *
* Copyright (C) 2011-2013 *
* Dominik Charousset <dominik.charousset@haw-hamburg.de> *
* *
* This file is part of libcppa. *
* libcppa is free software: you can redistribute it and/or modify it under *
* the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation, either version 3 of the License *
* or (at your option) any later version. *
* *
* libcppa is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with libcppa. If not, see <http://www.gnu.org/licenses/>. *
\******************************************************************************/
#ifndef CPPA_INTRUSIVE_FWD_PTR_HPP
#define CPPA_INTRUSIVE_FWD_PTR_HPP
#include <memory>
#include "cppa/util/comparable.hpp"
namespace cppa {
/**
* @brief A reference counting smart pointer implementation that
* can be used with forward declarated types.
* @warning libcppa assumes T is derived from ref_counted and
* implicitly converts intrusive_fwd_ptr to intrusive_ptr
* @relates intrusive_ptr
* @relates ref_counted
*/
template<typename T, typename Ref, typename Deref>
class intrusive_fwd_ptr : util::comparable<intrusive_fwd_ptr<T,Ref,Deref> >,
util::comparable<intrusive_fwd_ptr<T,Ref,Deref>, const T*>,
util::comparable<intrusive_fwd_ptr<T,Ref,Deref>, std::nullptr_t> {
public:
typedef T* pointer;
typedef const T* const_pointer;
typedef T element_type;
typedef T& reference;
typedef const T& const_reference;
intrusive_fwd_ptr(pointer raw_ptr = nullptr, Ref ref = Ref(), Deref deref = Deref())
: m_ref(std::move(ref)), m_deref(std::move(deref)) { set_ptr(raw_ptr); }
intrusive_fwd_ptr(intrusive_fwd_ptr&& other)
: m_ref(std::move(other.m_ref))
, m_deref(std::move(m_deref))
, m_ptr(other.release()) { }
intrusive_fwd_ptr(const intrusive_fwd_ptr& other)
: m_ref(other.m_ref), m_deref(other.m_deref) { set_ptr(other.get()); }
~intrusive_fwd_ptr() { if (m_ptr) m_deref(m_ptr); }
inline void swap(intrusive_fwd_ptr& other) {
std::swap(m_ptr, other.m_ptr);
}
/**
* @brief Returns the raw pointer without modifying reference count.
*/
pointer release() {
auto result = m_ptr;
m_ptr = nullptr;
return result;
}
/**
* @brief Sets this pointer to @p ptr without modifying reference count.
*/
void adopt(pointer ptr) {
reset();
m_ptr = ptr;
}
void reset(pointer new_value = nullptr) {
if (m_ptr) m_deref(m_ptr);
set_ptr(new_value);
}
template<typename... Args>
void emplace(Args&&... args) {
reset(new T(std::forward<Args>(args)...));
}
intrusive_fwd_ptr& operator=(pointer ptr) {
reset(ptr);
return *this;
}
intrusive_fwd_ptr& operator=(intrusive_fwd_ptr&& other) {
swap(other);
return *this;
}
intrusive_fwd_ptr& operator=(const intrusive_fwd_ptr& other) {
intrusive_fwd_ptr tmp(other);
swap(tmp);
return *this;
}
inline pointer get() const { return m_ptr; }
inline pointer operator->() const { return m_ptr; }
inline reference operator*() const { return *m_ptr; }
inline bool operator!() const { return m_ptr == nullptr; }
inline explicit operator bool() const { return m_ptr != nullptr; }
inline ptrdiff_t compare(const_pointer ptr) const {
return static_cast<ptrdiff_t>(get() - ptr);
}
inline ptrdiff_t compare(const intrusive_fwd_ptr& other) const {
return compare(other.get());
}
inline ptrdiff_t compare(std::nullptr_t) const {
return reinterpret_cast<ptrdiff_t>(get());
}
private:
Ref m_ref;
Deref m_deref;
pointer m_ptr;
inline void set_ptr(pointer raw_ptr) {
m_ptr = raw_ptr;
if (raw_ptr) m_ref(raw_ptr);
}
};
/**
* @relates intrusive_ptr
*/
template<typename T, typename Ref, typename Deref>
inline bool operator==(const intrusive_fwd_ptr<T,Ref,Deref>& lhs,
const intrusive_fwd_ptr<T,Ref,Deref>& rhs) {
return lhs.get() == rhs.get();
}
/**
* @relates intrusive_ptr
*/
template<typename T, typename Ref, typename Deref>
inline bool operator!=(const intrusive_fwd_ptr<T,Ref,Deref>& lhs,
const intrusive_fwd_ptr<T,Ref,Deref>& rhs) {
return !(lhs == rhs);
}
} // namespace cppa
#endif // CPPA_INTRUSIVE_FWD_PTR_HPP
...@@ -36,7 +36,6 @@ ...@@ -36,7 +36,6 @@
#include <stdexcept> #include <stdexcept>
#include <type_traits> #include <type_traits>
#include "cppa/intrusive_fwd_ptr.hpp"
#include "cppa/util/comparable.hpp" #include "cppa/util/comparable.hpp"
namespace cppa { namespace cppa {
...@@ -73,12 +72,6 @@ class intrusive_ptr : util::comparable<intrusive_ptr<T> >, ...@@ -73,12 +72,6 @@ class intrusive_ptr : util::comparable<intrusive_ptr<T> >,
intrusive_ptr(const intrusive_ptr& other) { set_ptr(other.get()); } intrusive_ptr(const intrusive_ptr& other) { set_ptr(other.get()); }
template<typename Y, typename Ref, typename Deref>
intrusive_ptr(intrusive_fwd_ptr<Y,Ref,Deref> other) : m_ptr(other.release()) {
static_assert(std::is_convertible<Y*, T*>::value,
"Y* is not assignable to T*");
}
template<typename Y> template<typename Y>
intrusive_ptr(intrusive_ptr<Y> other) : m_ptr(other.release()) { intrusive_ptr(intrusive_ptr<Y> other) : m_ptr(other.release()) {
static_assert(std::is_convertible<Y*, T*>::value, static_assert(std::is_convertible<Y*, T*>::value,
......
This diff is collapsed.
...@@ -56,7 +56,7 @@ class message_future { ...@@ -56,7 +56,7 @@ class message_future {
public: public:
inline continue_helper(message_id_t mid) : m_mid(mid) { } inline continue_helper(message_id mid) : m_mid(mid) { }
template<typename F> template<typename F>
void continue_with(F fun) { void continue_with(F fun) {
...@@ -71,7 +71,7 @@ class message_future { ...@@ -71,7 +71,7 @@ class message_future {
private: private:
message_id_t m_mid; message_id m_mid;
}; };
...@@ -127,16 +127,16 @@ class message_future { ...@@ -127,16 +127,16 @@ class message_future {
/** /**
* @brief Returns the awaited response ID. * @brief Returns the awaited response ID.
*/ */
inline const message_id_t& id() const { return m_mid; } inline const message_id& id() const { return m_mid; }
message_future(const message_future&) = default; message_future(const message_future&) = default;
message_future& operator=(const message_future&) = default; message_future& operator=(const message_future&) = default;
inline message_future(const message_id_t& from) : m_mid(from) { } inline message_future(const message_id& from) : m_mid(from) { }
private: private:
message_id_t m_mid; message_id m_mid;
template<typename... Fs> template<typename... Fs>
behavior fs2bhvr(Fs... fs) { behavior fs2bhvr(Fs... fs) {
...@@ -169,9 +169,9 @@ class sync_handle_helper { ...@@ -169,9 +169,9 @@ class sync_handle_helper {
inline sync_handle_helper(const message_future& mf) : m_mf(mf) { } inline sync_handle_helper(const message_future& mf) : m_mf(mf) { }
template<typename... Args> template<typename... Ts>
inline message_future::continue_helper operator()(Args&&... args) { inline message_future::continue_helper operator()(Ts&&... args) {
return m_mf.then(std::forward<Args>(args)...); return m_mf.then(std::forward<Ts>(args)...);
} }
private: private:
......
...@@ -42,7 +42,7 @@ struct invalid_message_id { constexpr invalid_message_id() { } }; ...@@ -42,7 +42,7 @@ struct invalid_message_id { constexpr invalid_message_id() { } };
* @brief * @brief
* @note Asynchronous messages always have an invalid message id. * @note Asynchronous messages always have an invalid message id.
*/ */
class message_id_t : util::comparable<message_id_t> { class message_id : util::comparable<message_id> {
static constexpr std::uint64_t response_flag_mask = 0x8000000000000000; static constexpr std::uint64_t response_flag_mask = 0x8000000000000000;
static constexpr std::uint64_t answered_flag_mask = 0x4000000000000000; static constexpr std::uint64_t answered_flag_mask = 0x4000000000000000;
...@@ -50,14 +50,14 @@ class message_id_t : util::comparable<message_id_t> { ...@@ -50,14 +50,14 @@ class message_id_t : util::comparable<message_id_t> {
public: public:
constexpr message_id_t() : m_value(0) { } constexpr message_id() : m_value(0) { }
message_id_t(message_id_t&&) = default; message_id(message_id&&) = default;
message_id_t(const message_id_t&) = default; message_id(const message_id&) = default;
message_id_t& operator=(message_id_t&&) = default; message_id& operator=(message_id&&) = default;
message_id_t& operator=(const message_id_t&) = default; message_id& operator=(const message_id&) = default;
inline message_id_t& operator++() { inline message_id& operator++() {
++m_value; ++m_value;
return *this; return *this;
} }
...@@ -78,12 +78,12 @@ class message_id_t : util::comparable<message_id_t> { ...@@ -78,12 +78,12 @@ class message_id_t : util::comparable<message_id_t> {
return valid() && !is_response(); return valid() && !is_response();
} }
inline message_id_t response_id() const { inline message_id response_id() const {
return message_id_t(valid() ? m_value | response_flag_mask : 0); return message_id(valid() ? m_value | response_flag_mask : 0);
} }
inline message_id_t request_id() const { inline message_id request_id() const {
return message_id_t(m_value & request_id_mask); return message_id(m_value & request_id_mask);
} }
inline void mark_as_answered() { inline void mark_as_answered() {
...@@ -94,24 +94,24 @@ class message_id_t : util::comparable<message_id_t> { ...@@ -94,24 +94,24 @@ class message_id_t : util::comparable<message_id_t> {
return m_value; return m_value;
} }
static inline message_id_t from_integer_value(std::uint64_t value) { static inline message_id from_integer_value(std::uint64_t value) {
message_id_t result; message_id result;
result.m_value = value; result.m_value = value;
return result; return result;
} }
static constexpr invalid_message_id invalid = invalid_message_id{}; static constexpr invalid_message_id invalid = invalid_message_id{};
constexpr message_id_t(invalid_message_id) : m_value(0) { } constexpr message_id(invalid_message_id) : m_value(0) { }
long compare(const message_id_t& other) const { long compare(const message_id& other) const {
return (m_value == other.m_value) return (m_value == other.m_value)
? 0 : ((m_value < other.m_value) ? -1 : 1); ? 0 : ((m_value < other.m_value) ? -1 : 1);
} }
private: private:
explicit constexpr message_id_t(std::uint64_t value) : m_value(value) { } explicit constexpr message_id(std::uint64_t value) : m_value(value) { }
std::uint64_t m_value; std::uint64_t m_value;
......
...@@ -36,8 +36,6 @@ ...@@ -36,8 +36,6 @@
#include "cppa/config.hpp" #include "cppa/config.hpp"
#include "cppa/ref_counted.hpp" #include "cppa/ref_counted.hpp"
#include "cppa/network/protocol.hpp"
namespace cppa { namespace network { namespace cppa { namespace network {
class middleman; class middleman;
......
...@@ -59,11 +59,11 @@ class sync_request_info : public extend<memory_managed,sync_request_info>:: ...@@ -59,11 +59,11 @@ class sync_request_info : public extend<memory_managed,sync_request_info>::
pointer next; // intrusive next pointer pointer next; // intrusive next pointer
actor_ptr sender; // points to the sender of the message actor_ptr sender; // points to the sender of the message
message_id_t mid; // sync message ID message_id mid; // sync message ID
private: private:
sync_request_info(actor_ptr sptr, message_id_t id); sync_request_info(actor_ptr sptr, message_id id);
}; };
...@@ -79,7 +79,7 @@ class default_actor_proxy : public actor_proxy { ...@@ -79,7 +79,7 @@ class default_actor_proxy : public actor_proxy {
void enqueue(const actor_ptr& sender, any_tuple msg); void enqueue(const actor_ptr& sender, any_tuple msg);
void sync_enqueue(const actor_ptr& sender, message_id_t id, any_tuple msg); void sync_enqueue(const actor_ptr& sender, message_id id, any_tuple msg);
void link_to(const actor_ptr& other); void link_to(const actor_ptr& other);
...@@ -107,7 +107,7 @@ class default_actor_proxy : public actor_proxy { ...@@ -107,7 +107,7 @@ class default_actor_proxy : public actor_proxy {
void forward_msg(const actor_ptr& sender, void forward_msg(const actor_ptr& sender,
any_tuple msg, any_tuple msg,
message_id_t mid = message_id_t()); message_id mid = message_id());
default_protocol_ptr m_proto; default_protocol_ptr m_proto;
process_information_ptr m_pinf; process_information_ptr m_pinf;
......
...@@ -49,13 +49,13 @@ class message_header { ...@@ -49,13 +49,13 @@ class message_header {
actor_ptr sender; actor_ptr sender;
actor_ptr receiver; actor_ptr receiver;
message_id_t id; message_id id;
message_header(); message_header();
message_header(const actor_ptr& sender, message_header(const actor_ptr& sender,
const actor_ptr& receiver, const actor_ptr& receiver,
message_id_t id = message_id_t::invalid); message_id id = message_id::invalid);
inline void deliver(any_tuple msg) const { inline void deliver(any_tuple msg) const {
if (receiver) { if (receiver) {
......
...@@ -36,15 +36,16 @@ ...@@ -36,15 +36,16 @@
#include <memory> #include <memory>
#include <functional> #include <functional>
#include "cppa/network/protocol.hpp"
#include "cppa/network/acceptor.hpp"
#include "cppa/network/continuable_reader.hpp" #include "cppa/network/continuable_reader.hpp"
#include "cppa/network/continuable_io.hpp"
namespace cppa { namespace detail { class singleton_manager; } } namespace cppa { namespace detail { class singleton_manager; } }
namespace cppa { namespace network { namespace cppa { namespace network {
class protocol;
typedef intrusive_ptr<protocol> protocol_ptr;
/** /**
* @brief Multiplexes asynchronous IO. * @brief Multiplexes asynchronous IO.
*/ */
......
...@@ -39,9 +39,9 @@ ...@@ -39,9 +39,9 @@
#include "cppa/actor.hpp" #include "cppa/actor.hpp"
#include "cppa/ref_counted.hpp" #include "cppa/ref_counted.hpp"
#include "cppa/primitive_variant.hpp" #include "cppa/primitive_variant.hpp"
#include "cppa/intrusive_fwd_ptr.hpp"
#include "cppa/network/acceptor.hpp" #include "cppa/network/acceptor.hpp"
#include "cppa/network/middleman.hpp"
namespace cppa { class actor_addressing; } namespace cppa { class actor_addressing; }
...@@ -83,14 +83,6 @@ class protocol : public ref_counted { ...@@ -83,14 +83,6 @@ class protocol : public ref_counted {
void run_later(std::function<void()> fun); void run_later(std::function<void()> fun);
struct ref_ftor {
void operator()(abstract_middleman*) const;
};
struct deref_ftor {
void operator()(abstract_middleman*) const;
};
protected: protected:
// note: not thread-safe; call only in run_later functor! // note: not thread-safe; call only in run_later functor!
...@@ -111,7 +103,7 @@ class protocol : public ref_counted { ...@@ -111,7 +103,7 @@ class protocol : public ref_counted {
private: private:
intrusive_fwd_ptr<abstract_middleman,ref_ftor,deref_ftor> m_parent; intrusive_ptr<abstract_middleman> m_parent;
}; };
......
...@@ -119,7 +119,7 @@ class object { ...@@ -119,7 +119,7 @@ class object {
/** /**
* @brief Creates a (deep) copy of @p other and assigns it to @p this. * @brief Creates a (deep) copy of @p other and assigns it to @p this.
* @return @p *this * @returns @p *this
*/ */
object& operator=(const object& other); object& operator=(const object& other);
......
...@@ -61,60 +61,54 @@ class partial_function { ...@@ -61,60 +61,54 @@ class partial_function {
public: public:
/** @cond PRIVATE */
typedef intrusive_ptr<detail::behavior_impl> impl_ptr; typedef intrusive_ptr<detail::behavior_impl> impl_ptr;
inline auto as_behavior_impl() const -> const impl_ptr&;
partial_function(impl_ptr ptr);
static constexpr bool may_have_timeout = false; static constexpr bool may_have_timeout = false;
/** @endcond */
partial_function() = default; partial_function() = default;
partial_function(partial_function&&) = default; partial_function(partial_function&&) = default;
partial_function(const partial_function&) = default; partial_function(const partial_function&) = default;
partial_function& operator=(partial_function&&) = default; partial_function& operator=(partial_function&&) = default;
partial_function& operator=(const partial_function&) = default; partial_function& operator=(const partial_function&) = default;
template<typename... Cases> template<typename... Cs>
partial_function(const match_expr<Cases...>& mexpr) partial_function(const match_expr<Cs...>& mexpr);
: m_impl(mexpr.as_behavior_impl()) { }
partial_function(impl_ptr ptr);
inline bool undefined() const {
return m_impl == nullptr;
}
inline bool defined_at(const any_tuple& value) {
return (m_impl) && m_impl->defined_at(value);
}
template<typename T>
inline bool operator()(T&& arg) {
return (m_impl) && m_impl->invoke(std::forward<T>(arg));
}
inline partial_function or_else(const partial_function& other) const {
return m_impl->or_else(other.m_impl);
}
inline behavior or_else(const behavior& other) const {
return behavior{m_impl->or_else(other.m_impl)};
}
/**
* @brief Returns @p true if this partial function is defined for the
* types of @p value, false otherwise.
*/
inline bool defined_at(const any_tuple& value);
/**
* @brief Returns @p true if this partial function was applied to
* @p args, false otherwise.
* @note This member function can return @p false even if
* {@link defined_at()} returns @p true, because {@link defined_at()}
* does <b>not</b> evaluate guards.
*/
template<typename T> template<typename T>
typename std::conditional<T::may_have_timeout,behavior,partial_function>::type inline bool operator()(T&& arg);
or_else(const T& arg) const;
template<typename T0, typename T1, typename... Ts> /**
* @brief Adds a fallback which is used where
* this partial function is not defined.
*/
template<typename... Ts>
typename std::conditional< typename std::conditional<
util::disjunction< util::disjunction<Ts::may_have_timeout...>::value,
T0::may_have_timeout,
T1::may_have_timeout,
Ts::may_have_timeout...
>::value,
behavior, behavior,
partial_function partial_function
>::type >::type
or_else(const T0& arg0, const T1& arg1, const Ts&... args) const; or_else(Ts&&... args) const;
inline const impl_ptr& as_behavior_impl() const;
private: private:
...@@ -122,45 +116,57 @@ class partial_function { ...@@ -122,45 +116,57 @@ class partial_function {
}; };
template<typename T, typename... Ts> template<typename T>
typename std::conditional<T::may_have_timeout,behavior,partial_function>::type
match_expr_convert(const T& arg) {
return {arg};
}
template<typename T0, typename T1, typename... Ts>
typename std::conditional< typename std::conditional<
util::disjunction< util::disjunction<
T::may_have_timeout, T0::may_have_timeout,
T1::may_have_timeout,
Ts::may_have_timeout... Ts::may_have_timeout...
>::value, >::value,
behavior, behavior,
partial_function partial_function
>::type >::type
match_expr_convert(const T& arg0, const Ts&... args) { match_expr_convert(const T0& arg0, const T1& arg1, const Ts&... args) {
return detail::match_expr_concat(arg0, args...); return detail::match_expr_concat(arg0, arg1, args...);
} }
/****************************************************************************** /******************************************************************************
* inline and template member function implementations * * inline and template member function implementations *
******************************************************************************/ ******************************************************************************/
inline const partial_function::impl_ptr& partial_function::as_behavior_impl() const { template<typename... Cs>
return m_impl; partial_function::partial_function(const match_expr<Cs...>& mexpr)
: m_impl(mexpr.as_behavior_impl()) { }
inline bool partial_function::defined_at(const any_tuple& value) {
return (m_impl) && m_impl->defined_at(value);
} }
template<typename T> template<typename T>
typename std::conditional<T::may_have_timeout,behavior,partial_function>::type inline bool partial_function::operator()(T&& arg) {
partial_function::or_else(const T& arg) const { return (m_impl) && m_impl->invoke(std::forward<T>(arg));
return m_impl->or_else(arg.as_behavior_impl());
} }
template<typename T0, typename T1, typename... Ts> template<typename... Ts>
typename std::conditional< typename std::conditional<
util::disjunction< util::disjunction<Ts::may_have_timeout...>::value,
T0::may_have_timeout,
T1::may_have_timeout,
Ts::may_have_timeout...
>::value,
behavior, behavior,
partial_function partial_function
>::type >::type
partial_function::or_else(const T0& arg0, const T1& arg1, const Ts&... args) const { partial_function::or_else(Ts&&... args) const {
return m_impl->or_else(match_expr_convert(arg0, arg1, args...).as_behavior_impl()); auto tmp = match_expr_convert(std::forward<Ts>(args)...);
return m_impl->or_else(tmp.as_behavior_impl());
}
inline auto partial_function::as_behavior_impl() const -> const impl_ptr& {
return m_impl;
} }
} // namespace cppa } // namespace cppa
......
...@@ -38,62 +38,64 @@ ...@@ -38,62 +38,64 @@
namespace cppa { namespace cppa {
#ifdef CPPA_DOCUMENTATION /**
* @ingroup BlockingAPI
* @{
*/
/** /**
* @brief Dequeues the next message from the mailbox that's matched * @brief Dequeues the next message from the mailbox that
* by @p bhvr and executes the corresponding callback. * is matched by given behavior.
* @param bhvr Denotes the actor's response the next incoming message.
*/ */
void receive(behavior& bhvr); template<typename... Ts>
void receive(Ts&&... args);
/** /**
* @brief Receives messages in an endless loop. * @brief Receives messages in an endless loop.
* * Semantically equal to: <tt>for (;;) { receive(...); }</tt>
* Semantically equal to: <tt>for (;;) { receive(bhvr); }</tt>
* @param bhvr Denotes the actor's response the next incoming message.
*/ */
void receive_loop(behavior& bhvr); template<typename... Ts>
void receive_loop(Ts&&... args);
/** /**
* @brief Receives messages as long as @p stmt returns true. * @brief Receives messages as in a range-based loop.
* *
* Semantically equal to: <tt>while (stmt()) { receive(...); }</tt>. * Semantically equal to:
* <tt>for ( ; begin != end; ++begin) { receive(...); }</tt>.
* *
* <b>Usage example:</b> * <b>Usage example:</b>
* @code * @code
* int i = 0; * int i = 0;
* receive_while([&]() { return (++i <= 10); }) * receive_for(i, 10) (
* ( * on(atom("get")) >> [&]() { reply("result", i); }
* on<int>() >> int_fun,
* on<float>() >> float_fun
* ); * );
* @endcode * @endcode
* @param stmt Lambda expression, functor or function returning a @c bool. * @param begin First value in range.
* @param end Last value in range (excluded).
* @returns A functor implementing the loop. * @returns A functor implementing the loop.
*/ */
template<typename Statement> template<typename T>
auto receive_while(Statement&& stmt); detail::receive_for_helper<T> receive_for(T& begin, const T& end);
/** /**
* @brief Receives messages as in a range-based loop. * @brief Receives messages as long as @p stmt returns true.
* *
* Semantically equal to: <tt>for ( ; begin != end; ++begin) { receive(...); }</tt>. * Semantically equal to: <tt>while (stmt()) { receive(...); }</tt>.
* *
* <b>Usage example:</b> * <b>Usage example:</b>
* @code * @code
* int i = 0; * int i = 0;
* receive_for(i, 10) * receive_while([&]() { return (++i <= 10); })
* ( * (
* on(atom("get")) >> [&]() { reply("result", i); } * on<int>() >> int_fun,
* on<float>() >> float_fun
* ); * );
* @endcode * @endcode
* @param begin First value in range. * @param stmt Lambda expression, functor or function returning a @c bool.
* @param end Last value in range (excluded).
* @returns A functor implementing the loop. * @returns A functor implementing the loop.
*/ */
template<typename T> template<typename Statement>
auto receive_for(T& begin, const T& end); detail::receive_while_helper<Statement> receive_while(Statement&& stmt);
/** /**
* @brief Receives messages until @p stmt returns true. * @brief Receives messages until @p stmt returns true.
...@@ -113,32 +115,34 @@ auto receive_for(T& begin, const T& end); ...@@ -113,32 +115,34 @@ auto receive_for(T& begin, const T& end);
* @param bhvr Denotes the actor's response the next incoming message. * @param bhvr Denotes the actor's response the next incoming message.
* @returns A functor providing the @c until member function. * @returns A functor providing the @c until member function.
*/ */
auto do_receive(behavior& bhvr); template<typename... Args>
detail::do_receive_helper do_receive(Args&&... args);
#else // CPPA_DOCUMENTATION /**
* @}
*/
inline void receive(behavior& bhvr) { self->dequeue(bhvr); }
inline void receive(partial_function& fun) { self->dequeue(fun); } /******************************************************************************
* inline and template function implementations *
******************************************************************************/
template<typename Arg0, typename... Args> template<typename... Ts>
void receive(Arg0&& arg0, Args&&... args) { void receive(Ts&&... args) {
auto tmp = match_expr_convert(std::forward<Arg0>(arg0), static_assert(sizeof...(Ts), "receive() requires at least one argument");
std::forward<Args>(args)...); self->dequeue(match_expr_convert(std::forward<Ts>(args)...));
receive(tmp);
} }
void receive_loop(behavior& rules); inline void receive_loop(behavior rules) {
void receive_loop(behavior&& rules); local_actor* sptr = self;
for (;;) sptr->dequeue(rules);
void receive_loop(partial_function& rules); }
void receive_loop(partial_function&& rules);
template<typename Arg0, typename... Args> template<typename... Ts>
void receive_loop(Arg0&& arg0, Args&&... args) { void receive_loop(Ts&&... args) {
auto tmp = match_expr_convert(std::forward<Arg0>(arg0), behavior bhvr = match_expr_convert(std::forward<Ts>(args)...);
std::forward<Args>(args)...); local_actor* sptr = self;
receive_loop(tmp); for (;;) sptr->dequeue(bhvr);
} }
template<typename T> template<typename T>
...@@ -153,13 +157,12 @@ detail::receive_while_helper<Statement> receive_while(Statement&& stmt) { ...@@ -153,13 +157,12 @@ detail::receive_while_helper<Statement> receive_while(Statement&& stmt) {
return std::move(stmt); return std::move(stmt);
} }
template<typename... Args> template<typename... Ts>
detail::do_receive_helper do_receive(Args&&... args) { detail::do_receive_helper do_receive(Ts&&... args) {
return detail::do_receive_helper(std::forward<Args>(args)...); behavior bhvr = match_expr_convert(std::forward<Ts>(args)...);
return detail::do_receive_helper(std::move(bhvr));
} }
#endif // CPPA_DOCUMENTATION
} // namespace cppa } // namespace cppa
#endif // CPPA_RECEIVE_HPP #endif // CPPA_RECEIVE_HPP
...@@ -52,7 +52,7 @@ class response_handle { ...@@ -52,7 +52,7 @@ class response_handle {
response_handle(const actor_ptr& from, response_handle(const actor_ptr& from,
const actor_ptr& to, const actor_ptr& to,
const message_id_t& response_id); const message_id& response_id);
/** /**
* @brief Queries whether response message is still outstanding. * @brief Queries whether response message is still outstanding.
...@@ -73,7 +73,7 @@ class response_handle { ...@@ -73,7 +73,7 @@ class response_handle {
/** /**
* @brief Returns the message id for the response message. * @brief Returns the message id for the response message.
*/ */
inline const message_id_t& response_id() const { return m_id; } inline const message_id& response_id() const { return m_id; }
/** /**
* @brief Returns the actor that is going send the response message. * @brief Returns the actor that is going send the response message.
...@@ -89,7 +89,7 @@ class response_handle { ...@@ -89,7 +89,7 @@ class response_handle {
actor_ptr m_from; actor_ptr m_from;
actor_ptr m_to; actor_ptr m_to;
message_id_t m_id; message_id m_id;
}; };
......
...@@ -119,9 +119,9 @@ class scheduled_actor : public extend<local_actor,scheduled_actor>::with<mailbox ...@@ -119,9 +119,9 @@ class scheduled_actor : public extend<local_actor,scheduled_actor>::with<mailbox
bool chained_enqueue(const actor_ptr&, any_tuple); bool chained_enqueue(const actor_ptr&, any_tuple);
void sync_enqueue(const actor_ptr&, message_id_t, any_tuple); void sync_enqueue(const actor_ptr&, message_id, any_tuple);
bool chained_sync_enqueue(const actor_ptr&, message_id_t, any_tuple); bool chained_sync_enqueue(const actor_ptr&, message_id, any_tuple);
void request_timeout(const util::duration& d); void request_timeout(const util::duration& d);
...@@ -195,7 +195,7 @@ class scheduled_actor : public extend<local_actor,scheduled_actor>::with<mailbox ...@@ -195,7 +195,7 @@ class scheduled_actor : public extend<local_actor,scheduled_actor>::with<mailbox
bool sync_enqueue_impl(actor_state next, bool sync_enqueue_impl(actor_state next,
const actor_ptr& sender, const actor_ptr& sender,
any_tuple& msg, any_tuple& msg,
message_id_t id); message_id id);
bool m_has_pending_tout; bool m_has_pending_tout;
std::uint32_t m_pending_tout; std::uint32_t m_pending_tout;
......
...@@ -144,7 +144,7 @@ class scheduler { ...@@ -144,7 +144,7 @@ class scheduler {
template<typename Duration, typename... Data> template<typename Duration, typename... Data>
void delayed_reply(const actor_ptr& to, void delayed_reply(const actor_ptr& to,
const Duration& rel_time, const Duration& rel_time,
message_id_t id, message_id id,
any_tuple data ) { any_tuple data ) {
CPPA_REQUIRE(!id.valid() || id.is_response()); CPPA_REQUIRE(!id.valid() || id.is_response());
if (id.valid()) { if (id.valid()) {
......
...@@ -61,15 +61,11 @@ class stacked : public Base { ...@@ -61,15 +61,11 @@ class stacked : public Base {
static constexpr auto receive_flag = detail::rp_nestable; static constexpr auto receive_flag = detail::rp_nestable;
virtual void dequeue(partial_function& fun) {
m_recv_policy.receive(dthis(), fun);
}
virtual void dequeue(behavior& bhvr) { virtual void dequeue(behavior& bhvr) {
m_recv_policy.receive(dthis(), bhvr); m_recv_policy.receive(dthis(), bhvr);
} }
virtual void dequeue_response(behavior& bhvr, message_id_t request_id) { virtual void dequeue_response(behavior& bhvr, message_id request_id) {
m_recv_policy.receive(dthis(), bhvr, request_id); m_recv_policy.receive(dthis(), bhvr, request_id);
} }
...@@ -98,10 +94,10 @@ class stacked : public Base { ...@@ -98,10 +94,10 @@ class stacked : public Base {
: Base(std::forward<Args>(args)...), m_behavior(std::move(fun)) { } : Base(std::forward<Args>(args)...), m_behavior(std::move(fun)) { }
virtual void do_become(behavior&& bhvr, bool discard_old) { virtual void do_become(behavior&& bhvr, bool discard_old) {
become_impl(std::move(bhvr), discard_old, message_id_t()); become_impl(std::move(bhvr), discard_old, message_id());
} }
virtual void become_waiting_for(behavior&& bhvr, message_id_t mid) { virtual void become_waiting_for(behavior bhvr, message_id mid) {
become_impl(std::move(bhvr), false, mid); become_impl(std::move(bhvr), false, mid);
} }
...@@ -123,7 +119,7 @@ class stacked : public Base { ...@@ -123,7 +119,7 @@ class stacked : public Base {
std::function<void()> m_behavior; std::function<void()> m_behavior;
detail::receive_policy m_recv_policy; detail::receive_policy m_recv_policy;
void become_impl(behavior&& bhvr, bool discard_old, message_id_t mid) { void become_impl(behavior&& bhvr, bool discard_old, message_id mid) {
if (bhvr.timeout().valid()) { if (bhvr.timeout().valid()) {
dthis()->reset_timeout(); dthis()->reset_timeout();
dthis()->request_timeout(bhvr.timeout()); dthis()->request_timeout(bhvr.timeout());
......
...@@ -90,7 +90,7 @@ class thread_mapped_actor : public extend<local_actor,thread_mapped_actor>::with ...@@ -90,7 +90,7 @@ class thread_mapped_actor : public extend<local_actor,thread_mapped_actor>::with
void enqueue(const actor_ptr& sender, any_tuple msg); void enqueue(const actor_ptr& sender, any_tuple msg);
void sync_enqueue(const actor_ptr& sender, message_id_t id, any_tuple msg); void sync_enqueue(const actor_ptr& sender, message_id id, any_tuple msg);
inline void reset_timeout() { } inline void reset_timeout() { }
inline void request_timeout(const util::duration&) { } inline void request_timeout(const util::duration&) { }
......
...@@ -69,7 +69,7 @@ bool actor::chained_enqueue(const actor_ptr& sender, any_tuple msg) { ...@@ -69,7 +69,7 @@ bool actor::chained_enqueue(const actor_ptr& sender, any_tuple msg) {
return false; return false;
} }
bool actor::chained_sync_enqueue(const actor_ptr& ptr, message_id_t id, any_tuple msg) { bool actor::chained_sync_enqueue(const actor_ptr& ptr, message_id id, any_tuple msg) {
sync_enqueue(ptr, id, std::move(msg)); sync_enqueue(ptr, id, std::move(msg));
return false; return false;
} }
......
...@@ -62,7 +62,7 @@ struct behavior_stack_mover : iterator<output_iterator_tag,void,void,void,void>{ ...@@ -62,7 +62,7 @@ struct behavior_stack_mover : iterator<output_iterator_tag,void,void,void,void>{
inline behavior_stack_mover move_iter(behavior_stack* bs) { return {bs}; } inline behavior_stack_mover move_iter(behavior_stack* bs) { return {bs}; }
option<behavior&> behavior_stack::sync_handler(message_id_t expected_response) { option<behavior&> behavior_stack::sync_handler(message_id expected_response) {
if (expected_response.valid()) { if (expected_response.valid()) {
auto e = m_elements.rend(); auto e = m_elements.rend();
auto i = find_if(m_elements.rbegin(), e, [=](element_type& val) { auto i = find_if(m_elements.rbegin(), e, [=](element_type& val) {
......
...@@ -42,11 +42,11 @@ using namespace std; ...@@ -42,11 +42,11 @@ using namespace std;
namespace cppa { namespace network { namespace cppa { namespace network {
inline sync_request_info* new_req_info(actor_ptr sptr, message_id_t id) { inline sync_request_info* new_req_info(actor_ptr sptr, message_id id) {
return detail::memory::create<sync_request_info>(std::move(sptr), id); return detail::memory::create<sync_request_info>(std::move(sptr), id);
} }
sync_request_info::sync_request_info(actor_ptr sptr, message_id_t id) sync_request_info::sync_request_info(actor_ptr sptr, message_id id)
: next(nullptr), sender(std::move(sptr)), mid(id) { } : next(nullptr), sender(std::move(sptr)), mid(id) { }
default_actor_proxy::default_actor_proxy(actor_id mid, default_actor_proxy::default_actor_proxy(actor_id mid,
...@@ -89,7 +89,7 @@ void default_actor_proxy::deliver(const network::message_header& hdr, any_tuple ...@@ -89,7 +89,7 @@ void default_actor_proxy::deliver(const network::message_header& hdr, any_tuple
void default_actor_proxy::forward_msg(const actor_ptr& sender, void default_actor_proxy::forward_msg(const actor_ptr& sender,
any_tuple msg, any_tuple msg,
message_id_t mid) { message_id mid) {
CPPA_LOG_TRACE(""); CPPA_LOG_TRACE("");
if (sender && mid.is_request()) { if (sender && mid.is_request()) {
switch (m_pending_requests.enqueue(new_req_info(sender, mid))) { switch (m_pending_requests.enqueue(new_req_info(sender, mid))) {
...@@ -147,7 +147,7 @@ void default_actor_proxy::enqueue(const actor_ptr& sender, any_tuple msg) { ...@@ -147,7 +147,7 @@ void default_actor_proxy::enqueue(const actor_ptr& sender, any_tuple msg) {
} }
void default_actor_proxy::sync_enqueue(const actor_ptr& sender, void default_actor_proxy::sync_enqueue(const actor_ptr& sender,
message_id_t mid, message_id mid,
any_tuple msg) { any_tuple msg) {
CPPA_LOG_TRACE(CPPA_TARG(sender, to_string) << ", " CPPA_LOG_TRACE(CPPA_TARG(sender, to_string) << ", "
<< CPPA_MARG(mid, integer_value) << ", " << CPPA_MARG(mid, integer_value) << ", "
......
...@@ -78,11 +78,7 @@ void event_based_actor::dequeue(behavior&) { ...@@ -78,11 +78,7 @@ void event_based_actor::dequeue(behavior&) {
quit(exit_reason::unallowed_function_call); quit(exit_reason::unallowed_function_call);
} }
void event_based_actor::dequeue(partial_function&) { void event_based_actor::dequeue_response(behavior&, message_id) {
quit(exit_reason::unallowed_function_call);
}
void event_based_actor::dequeue_response(behavior&, message_id_t) {
quit(exit_reason::unallowed_function_call); quit(exit_reason::unallowed_function_call);
} }
...@@ -193,7 +189,7 @@ void event_based_actor::do_become(behavior&& bhvr, bool discard_old) { ...@@ -193,7 +189,7 @@ void event_based_actor::do_become(behavior&& bhvr, bool discard_old) {
m_bhvr_stack.push_back(std::move(bhvr)); m_bhvr_stack.push_back(std::move(bhvr));
} }
void event_based_actor::become_waiting_for(behavior&& bhvr, message_id_t mf) { void event_based_actor::become_waiting_for(behavior bhvr, message_id mf) {
if (bhvr.timeout().valid()) { if (bhvr.timeout().valid()) {
reset_timeout(); reset_timeout();
request_timeout(bhvr.timeout()); request_timeout(bhvr.timeout());
......
...@@ -75,11 +75,11 @@ local_actor::local_actor(bool sflag) ...@@ -75,11 +75,11 @@ 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) { }
void local_actor::monitor(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)});
} }
void local_actor::demonitor(actor_ptr whom) { void local_actor::demonitor(const actor_ptr& whom) {
attachable::token mtoken{typeid(down_observer), this}; attachable::token mtoken{typeid(down_observer), this};
if (whom) whom->detach(mtoken); if (whom) whom->detach(mtoken);
} }
...@@ -113,12 +113,12 @@ void local_actor::reply_message(any_tuple&& what) { ...@@ -113,12 +113,12 @@ void local_actor::reply_message(any_tuple&& what) {
} }
auto& id = m_current_node->mid; auto& id = m_current_node->mid;
if (id.valid() == false || id.is_response()) { if (id.valid() == false || id.is_response()) {
send_message(whom, std::move(what)); send_message(whom.get(), std::move(what));
} }
else if (!id.is_answered()) { else if (!id.is_answered()) {
if (chaining_enabled()) { if (chaining_enabled()) {
if (whom->chained_sync_enqueue(this, id.response_id(), std::move(what))) { if (whom->chained_sync_enqueue(this, id.response_id(), std::move(what))) {
m_chained_actor = whom; chained_actor(whom);
} }
} }
else { else {
...@@ -140,7 +140,7 @@ void local_actor::forward_message(const actor_ptr& new_receiver) { ...@@ -140,7 +140,7 @@ void local_actor::forward_message(const actor_ptr& new_receiver) {
else { else {
new_receiver->sync_enqueue(from.get(), id, m_current_node->msg); new_receiver->sync_enqueue(from.get(), id, m_current_node->msg);
// treat this message as asynchronous message from now on // treat this message as asynchronous message from now on
m_current_node->mid = message_id_t(); m_current_node->mid = message_id();
} }
} }
...@@ -151,7 +151,7 @@ response_handle local_actor::make_response_handle() { ...@@ -151,7 +151,7 @@ response_handle local_actor::make_response_handle() {
return std::move(result); return std::move(result);
} }
message_id_t local_actor::send_timed_sync_message(const actor_ptr& whom, message_id local_actor::send_timed_sync_message(const actor_ptr& whom,
const util::duration& rel_time, const util::duration& rel_time,
any_tuple&& what) { any_tuple&& what) {
auto mid = this->send_sync_message(whom, std::move(what)); auto mid = this->send_sync_message(whom, std::move(what));
...@@ -164,10 +164,6 @@ void local_actor::exec_behavior_stack() { ...@@ -164,10 +164,6 @@ void local_actor::exec_behavior_stack() {
// default implementation does nothing // default implementation does nothing
} }
sync_handle_helper local_actor::handle_response(const message_future& mf) {
return ::cppa::handle_response(mf);
}
void local_actor::cleanup(std::uint32_t reason) { void local_actor::cleanup(std::uint32_t reason) {
m_subscriptions.clear(); m_subscriptions.clear();
super::cleanup(reason); super::cleanup(reason);
......
...@@ -34,7 +34,7 @@ namespace cppa { namespace network { ...@@ -34,7 +34,7 @@ namespace cppa { namespace network {
message_header::message_header(const actor_ptr& s, message_header::message_header(const actor_ptr& s,
const actor_ptr& r, const actor_ptr& r,
message_id_t mid ) message_id mid )
: sender(s), receiver(r), id(mid) { } : sender(s), receiver(r), id(mid) { }
message_header::message_header() : sender(nullptr), receiver(nullptr), id() { } message_header::message_header() : sender(nullptr), receiver(nullptr), id() { }
......
...@@ -34,14 +34,6 @@ ...@@ -34,14 +34,6 @@
namespace cppa { namespace network { namespace cppa { namespace network {
void protocol::ref_ftor::operator()(abstract_middleman* ptr) const {
if (ptr) ptr->ref();
}
void protocol::deref_ftor::operator()(abstract_middleman* ptr) const {
if (ptr) ptr->deref();
}
protocol::protocol(abstract_middleman* parent) : m_parent(parent) { protocol::protocol(abstract_middleman* parent) : m_parent(parent) {
CPPA_REQUIRE(parent != nullptr); CPPA_REQUIRE(parent != nullptr);
} }
......
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_ *
* /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\ *
* \/____/ \/_/\/___/ \/____/ \ \ \/ \ \ \/ \/__/\/_/ *
* \ \_\ \ \_\ *
* \/_/ \/_/ *
* *
* Copyright (C) 2011-2013 *
* Dominik Charousset <dominik.charousset@haw-hamburg.de> *
* *
* This file is part of libcppa. *
* libcppa is free software: you can redistribute it and/or modify it under *
* the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation, either version 3 of the License *
* or (at your option) any later version. *
* *
* libcppa is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with libcppa. If not, see <http://www.gnu.org/licenses/>. *
\******************************************************************************/
#include "cppa/cppa.hpp"
#include "cppa/receive.hpp"
namespace cppa {
void receive_loop(behavior& rules) {
local_actor* sptr = self;
for (;;) {
sptr->dequeue(rules);
}
}
void receive_loop(behavior&& rules) {
behavior tmp(std::move(rules));
receive_loop(tmp);
}
void receive_loop(partial_function& rules) {
local_actor* sptr = self;
for (;;) {
sptr->dequeue(rules);
}
}
void receive_loop(partial_function&& rules) {
partial_function tmp(std::move(rules));
receive_loop(tmp);
}
} // namespace cppa
...@@ -34,7 +34,7 @@ namespace cppa { namespace detail { ...@@ -34,7 +34,7 @@ namespace cppa { namespace detail {
recursive_queue_node::recursive_queue_node(const actor_ptr& sptr, recursive_queue_node::recursive_queue_node(const actor_ptr& sptr,
any_tuple data, any_tuple data,
message_id_t id) message_id id)
: next(nullptr), marked(false), sender(sptr), msg(std::move(data)), mid(id) { } : next(nullptr), marked(false), sender(sptr), msg(std::move(data)), mid(id) { }
} } // namespace cppa::detail } } // namespace cppa::detail
...@@ -40,7 +40,7 @@ namespace cppa { ...@@ -40,7 +40,7 @@ namespace cppa {
response_handle::response_handle(const actor_ptr& from, response_handle::response_handle(const actor_ptr& from,
const actor_ptr& to, const actor_ptr& to,
const message_id_t& id) const message_id& id)
: m_from(from), m_to(to), m_id(id) { : m_from(from), m_to(to), m_id(id) {
CPPA_REQUIRE(id.is_response()); CPPA_REQUIRE(id.is_response());
} }
......
...@@ -133,7 +133,7 @@ bool scheduled_actor::enqueue(actor_state next_state, ...@@ -133,7 +133,7 @@ bool scheduled_actor::enqueue(actor_state next_state,
bool scheduled_actor::sync_enqueue_impl(actor_state next, bool scheduled_actor::sync_enqueue_impl(actor_state next,
const actor_ptr& sender, const actor_ptr& sender,
any_tuple& msg, any_tuple& msg,
message_id_t id) { message_id id) {
bool err = false; bool err = false;
auto ptr = new_mailbox_element(sender, std::move(msg), id); auto ptr = new_mailbox_element(sender, std::move(msg), id);
bool res = enqueue(next, &err, ptr); bool res = enqueue(next, &err, ptr);
...@@ -162,13 +162,13 @@ bool scheduled_actor::chained_enqueue(const actor_ptr& sender, any_tuple msg) { ...@@ -162,13 +162,13 @@ bool scheduled_actor::chained_enqueue(const actor_ptr& sender, any_tuple msg) {
} }
void scheduled_actor::sync_enqueue(const actor_ptr& sender, void scheduled_actor::sync_enqueue(const actor_ptr& sender,
message_id_t id, message_id id,
any_tuple msg) { any_tuple msg) {
sync_enqueue_impl(actor_state::ready, sender, msg, id); sync_enqueue_impl(actor_state::ready, sender, msg, id);
} }
bool scheduled_actor::chained_sync_enqueue(const actor_ptr& sender, bool scheduled_actor::chained_sync_enqueue(const actor_ptr& sender,
message_id_t id, message_id id,
any_tuple msg) { any_tuple msg) {
return sync_enqueue_impl(actor_state::pending, sender, msg, id); return sync_enqueue_impl(actor_state::pending, sender, msg, id);
} }
......
...@@ -38,14 +38,13 @@ scheduled_actor_dummy::scheduled_actor_dummy() ...@@ -38,14 +38,13 @@ scheduled_actor_dummy::scheduled_actor_dummy()
void scheduled_actor_dummy::enqueue(const actor_ptr&, any_tuple) { } void scheduled_actor_dummy::enqueue(const actor_ptr&, any_tuple) { }
void scheduled_actor_dummy::quit(std::uint32_t) { } void scheduled_actor_dummy::quit(std::uint32_t) { }
void scheduled_actor_dummy::dequeue(behavior&) { } void scheduled_actor_dummy::dequeue(behavior&) { }
void scheduled_actor_dummy::dequeue(partial_function&) { } void scheduled_actor_dummy::dequeue_response(behavior&, message_id) { }
void scheduled_actor_dummy::dequeue_response(behavior&, message_id_t) { }
void scheduled_actor_dummy::do_become(behavior&&, bool) { } void scheduled_actor_dummy::do_become(behavior&&, bool) { }
void scheduled_actor_dummy::become_waiting_for(behavior&&, message_id_t) { } void scheduled_actor_dummy::become_waiting_for(behavior, message_id) { }
bool scheduled_actor_dummy::has_behavior() { return false; } bool scheduled_actor_dummy::has_behavior() { return false; }
void scheduled_actor_dummy::sync_enqueue(const actor_ptr&, void scheduled_actor_dummy::sync_enqueue(const actor_ptr&,
message_id_t, message_id,
any_tuple) { } any_tuple) { }
resume_result scheduled_actor_dummy::resume(util::fiber*,actor_ptr&) { resume_result scheduled_actor_dummy::resume(util::fiber*,actor_ptr&) {
......
...@@ -68,13 +68,13 @@ class delayed_msg { ...@@ -68,13 +68,13 @@ class delayed_msg {
delayed_msg(const channel_ptr& arg0, delayed_msg(const channel_ptr& arg0,
const actor_ptr& arg1, const actor_ptr& arg1,
message_id_t, message_id,
any_tuple&& arg3) any_tuple&& arg3)
: ptr_a(arg0), from(arg1), msg(move(arg3)) { } : ptr_a(arg0), from(arg1), msg(move(arg3)) { }
delayed_msg(const actor_ptr& arg0, delayed_msg(const actor_ptr& arg0,
const actor_ptr& arg1, const actor_ptr& arg1,
message_id_t arg2, message_id arg2,
any_tuple&& arg3) any_tuple&& arg3)
: ptr_b(arg0), from(arg1), id(arg2), msg(move(arg3)) { } : ptr_b(arg0), from(arg1), id(arg2), msg(move(arg3)) { }
...@@ -94,7 +94,7 @@ class delayed_msg { ...@@ -94,7 +94,7 @@ class delayed_msg {
channel_ptr ptr_a; channel_ptr ptr_a;
actor_ptr ptr_b; actor_ptr ptr_b;
actor_ptr from; actor_ptr from;
message_id_t id; message_id id;
any_tuple msg; any_tuple msg;
}; };
...@@ -146,7 +146,7 @@ inline void insert_dmsg(Map& storage, ...@@ -146,7 +146,7 @@ inline void insert_dmsg(Map& storage,
const T& to, const T& to,
const actor_ptr& sender, const actor_ptr& sender,
any_tuple&& tup, any_tuple&& tup,
message_id_t id = message_id_t{}) { message_id id = message_id{}) {
auto tout = hrc::now(); auto tout = hrc::now();
tout += d; tout += d;
delayed_msg dmsg{to, sender, id, move(tup)}; delayed_msg dmsg{to, sender, id, move(tup)};
...@@ -170,7 +170,7 @@ void scheduler_helper::timer_loop(scheduler_helper::ptr_type m_self) { ...@@ -170,7 +170,7 @@ void scheduler_helper::timer_loop(scheduler_helper::ptr_type m_self) {
}, },
on(atom("REPLY"), arg_match) >> [&](const util::duration& d, on(atom("REPLY"), arg_match) >> [&](const util::duration& d,
const actor_ptr& ptr, const actor_ptr& ptr,
message_id_t id, message_id id,
any_tuple& tup) { any_tuple& tup) {
insert_dmsg(messages, d, ptr, msg_ptr->sender, move(tup), id); insert_dmsg(messages, d, ptr, msg_ptr->sender, move(tup), id);
}, },
......
...@@ -60,7 +60,7 @@ void thread_mapped_actor::enqueue(const actor_ptr& sender, any_tuple msg) { ...@@ -60,7 +60,7 @@ void thread_mapped_actor::enqueue(const actor_ptr& sender, any_tuple msg) {
} }
void thread_mapped_actor::sync_enqueue(const actor_ptr& sender, void thread_mapped_actor::sync_enqueue(const actor_ptr& sender,
message_id_t id, message_id id,
any_tuple msg) { any_tuple msg) {
auto ptr = this->new_mailbox_element(sender, std::move(msg), id); auto ptr = this->new_mailbox_element(sender, std::move(msg), id);
if (!this->m_mailbox.push_back(ptr)) { if (!this->m_mailbox.push_back(ptr)) {
......
...@@ -43,29 +43,27 @@ ...@@ -43,29 +43,27 @@
#include "cppa/atom.hpp" #include "cppa/atom.hpp"
#include "cppa/to_string.hpp" #include "cppa/to_string.hpp"
#include "cppa/exception.hpp" #include "cppa/exception.hpp"
#include "cppa/singletons.hpp"
#include "cppa/exit_reason.hpp" #include "cppa/exit_reason.hpp"
#include "cppa/binary_serializer.hpp" #include "cppa/binary_serializer.hpp"
#include "cppa/binary_deserializer.hpp" #include "cppa/binary_deserializer.hpp"
#include "cppa/intrusive/single_reader_queue.hpp" #include "cppa/intrusive/single_reader_queue.hpp"
#include "cppa/network/acceptor.hpp"
#include "cppa/network/protocol.hpp"
#include "cppa/network/middleman.hpp" #include "cppa/network/middleman.hpp"
#include "cppa/network/ipv4_acceptor.hpp" #include "cppa/network/ipv4_acceptor.hpp"
#include "cppa/network/ipv4_io_stream.hpp" #include "cppa/network/ipv4_io_stream.hpp"
#include "cppa/detail/actor_registry.hpp"
#include "cppa/detail/singleton_manager.hpp"
namespace cppa { namespace cppa {
using namespace detail; using namespace detail;
using namespace network; using namespace network;
namespace { namespace { protocol_ptr proto() {
protocol* proto() { return get_middleman()->protocol(atom("DEFAULT")).get();
return singleton_manager::get_middleman()->protocol(atom("DEFAULT")).get(); } }
}
} // namespace <anonymous>
void publish(actor_ptr whom, std::unique_ptr<acceptor> aptr) { void publish(actor_ptr whom, std::unique_ptr<acceptor> aptr) {
proto()->publish(whom, move(aptr), {}); proto()->publish(whom, move(aptr), {});
......
...@@ -412,7 +412,7 @@ class msg_hdr_tinfo : public util::abstract_uniform_type_info<network::message_h ...@@ -412,7 +412,7 @@ class msg_hdr_tinfo : public util::abstract_uniform_type_info<network::message_h
actor_ptr_tinfo::s_deserialize(msg.sender, source, actor_ptr_name); actor_ptr_tinfo::s_deserialize(msg.sender, source, actor_ptr_name);
actor_ptr_tinfo::s_deserialize(msg.receiver, source, actor_ptr_name); actor_ptr_tinfo::s_deserialize(msg.receiver, source, actor_ptr_name);
auto msg_id = source->read<std::uint64_t>(); auto msg_id = source->read<std::uint64_t>();
msg.id = message_id_t::from_integer_value(msg_id); msg.id = message_id::from_integer_value(msg_id);
source->end_object(); source->end_object();
} }
......
...@@ -461,7 +461,7 @@ int main() { ...@@ -461,7 +461,7 @@ int main() {
self->become ( self->become (
on("hi") >> [&]() { on("hi") >> [&]() {
auto handle = sync_send(self->last_sender(), "whassup?"); auto handle = sync_send(self->last_sender(), "whassup?");
self->handle_response(handle) ( handle_response(handle) (
on_arg_match >> [&](const string& str) { on_arg_match >> [&](const string& str) {
CPPA_CHECK(self->last_sender() != nullptr); CPPA_CHECK(self->last_sender() != nullptr);
CPPA_CHECK_EQUAL(str, "nothing"); CPPA_CHECK_EQUAL(str, "nothing");
......
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