Commit c6904641 authored by Dominik Charousset's avatar Dominik Charousset

Make delayed_anon_send a free function

parent 5d6cda55
......@@ -64,11 +64,11 @@ public:
group(intrusive_ptr<abstract_group> gptr);
inline explicit operator bool() const noexcept {
explicit operator bool() const noexcept {
return static_cast<bool>(ptr_);
}
inline bool operator!() const noexcept {
bool operator!() const noexcept {
return !ptr_;
}
......@@ -76,7 +76,7 @@ public:
intptr_t compare(const group& other) const noexcept;
inline intptr_t compare(const invalid_group_t&) const noexcept {
intptr_t compare(const invalid_group_t&) const noexcept {
return ptr_ ? 1 : 0;
}
......@@ -98,12 +98,16 @@ public:
friend error inspect(deserializer&, group&);
inline abstract_group* get() const noexcept {
abstract_group* get() const noexcept {
return ptr_.get();
}
/// @cond PRIVATE
actor_system& system() const {
return ptr_->system();
}
template <class... Ts>
void eq_impl(message_id mid, strong_actor_ptr sender,
execution_unit* ctx, Ts&&... xs) const {
......@@ -113,27 +117,25 @@ public:
make_message(std::forward<Ts>(xs)...), ctx);
}
inline bool subscribe(strong_actor_ptr who) const {
bool subscribe(strong_actor_ptr who) const {
if (!ptr_)
return false;
return ptr_->subscribe(std::move(who));
}
inline void unsubscribe(const actor_control_block* who) const {
void unsubscribe(const actor_control_block* who) const {
if (ptr_)
ptr_->unsubscribe(who);
}
/// CAF's messaging primitives assume a non-null guarantee. A group
/// object indirects pointer-like access to a group to prevent UB.
inline const group* operator->() const noexcept {
const group* operator->() const noexcept {
return this;
}
/// @endcond
private:
inline abstract_group* release() noexcept {
abstract_group* release() noexcept {
return ptr_.release();
}
......@@ -150,7 +152,7 @@ std::string to_string(const group& x);
namespace std {
template <>
struct hash<caf::group> {
inline size_t operator()(const caf::group& x) const {
size_t operator()(const caf::group& x) const {
// groups are singleton objects, the address is thus the best possible hash
return !x ? 0 : reinterpret_cast<size_t>(x.get());
}
......
......@@ -23,19 +23,18 @@
#include "caf/actor.hpp"
#include "caf/actor_cast.hpp"
#include "caf/actor_clock.hpp"
#include "caf/actor_control_block.hpp"
#include "caf/check_typed_input.hpp"
#include "caf/duration.hpp"
#include "caf/no_stages.hpp"
#include "caf/response_type.hpp"
#include "caf/response_handle.hpp"
#include "caf/fwd.hpp"
#include "caf/message.hpp"
#include "caf/message_priority.hpp"
#include "caf/no_stages.hpp"
#include "caf/response_handle.hpp"
#include "caf/response_type.hpp"
#include "caf/scheduler/abstract_coordinator.hpp"
#include "caf/send.hpp"
namespace caf {
namespace mixin {
......@@ -119,7 +118,8 @@ public:
template <message_priority P = message_priority::normal, class Rep = int,
class Period = std::ratio<1>, class Dest = actor, class... Ts>
void delayed_send(const Dest& dest, std::chrono::duration<Rep, Period> rtime,
detail::enable_if_t<!std::is_same<Dest, group>::value>
delayed_send(const Dest& dest, std::chrono::duration<Rep, Period> rtime,
Ts&&... xs) {
using token =
detail::type_list<
......@@ -156,56 +156,46 @@ public:
"this actor does not accept the response message");
if (dest) {
auto& clock = dptr()->system().clock();
auto t = clock.now() + rtime;
delayed_send_impl(clock, dptr()->ctrl(), dest, P, t,
std::forward<Ts>(xs)...);
auto timeout = clock.now() + rtime;
clock.schedule_message(timeout, actor_cast<strong_actor_ptr>(dest),
make_mailbox_element(dptr()->ctrl(),
make_message_id(P), no_stages,
std::forward<Ts>(xs)...));
}
}
template <message_priority P = message_priority::normal, class Dest = actor,
class Rep = int, class Period = std::ratio<1>, class... Ts>
void delayed_anon_send(const Dest& dest,
std::chrono::duration<Rep, Period> rtime, Ts&&... xs) {
static_assert(sizeof...(Ts) > 0, "no message to send");
using token =
detail::type_list<
typename detail::implicit_conversions<
typename std::decay<Ts>::type
>::type...>;
static_assert(response_type_unbox<
signatures_of_t<Dest>,
token
>::valid,
"receiver does not accept given message");
template <class Rep = int, class Period = std::ratio<1>, class Dest = actor,
class... Ts>
void delayed_send(const group& dest, std::chrono::duration<Rep, Period> rtime,
Ts&&... xs) {
static_assert(!statically_typed<Subtype>(),
"statically typed actors are not allowed to send to groups");
if (dest) {
auto& clock = dptr()->system().clock();
auto t = clock.now() + rtime;
delayed_send_impl(clock, nullptr, dest, P, t, std::forward<Ts>(xs)...);
auto timeout = clock.now() + rtime;
clock.schedule_message(timeout, dest, dptr()->ctrl(),
make_message(std::forward<Ts>(xs)...));
}
}
private:
Subtype* dptr() {
return static_cast<Subtype*>(this);
template <message_priority P = message_priority::normal, class Dest = actor,
class Rep = int, class Period = std::ratio<1>, class... Ts>
void delayed_anon_send(const Dest& dest,
std::chrono::duration<Rep, Period> rtime, Ts&&... xs)
CAF_DEPRECATED_MSG("use the free function instead") {
caf::delayed_anon_send<P>(dest, rtime, std::forward<Ts>(xs)...);
}
template <class... Ts>
static void delayed_send_impl(actor_clock& clk, strong_actor_ptr src,
const group& dst, message_priority,
actor_clock::time_point tout, Ts&&... xs) {
clk.schedule_message(tout, dst, std::move(src),
make_message(std::forward<Ts>(xs)...));
template <class Rep = int, class Period = std::ratio<1>, class... Ts>
void delayed_anon_send(const group& dest,
std::chrono::duration<Rep, Period> rtime, Ts&&... xs)
CAF_DEPRECATED_MSG("use the free function instead") {
caf::delayed_anon_send(dest, rtime, std::forward<Ts>(xs)...);
}
template <class ActorHandle, class... Ts>
static void delayed_send_impl(actor_clock& clk, strong_actor_ptr src,
const ActorHandle& dst, message_priority prio,
actor_clock::time_point tout,
Ts&&... xs) {
clk.schedule_message(tout, actor_cast<strong_actor_ptr>(dst),
make_mailbox_element(std::move(src),
make_message_id(prio), no_stages,
std::forward<Ts>(xs)...));
private:
Subtype* dptr() {
return static_cast<Subtype*>(this);
}
};
......
......@@ -19,17 +19,19 @@
#pragma once
#include "caf/actor.hpp"
#include "caf/message.hpp"
#include "caf/actor_cast.hpp"
#include "caf/actor_addr.hpp"
#include "caf/message_id.hpp"
#include "caf/typed_actor.hpp"
#include "caf/actor_cast.hpp"
#include "caf/check_typed_input.hpp"
#include "caf/is_message_sink.hpp"
#include "caf/local_actor.hpp"
#include "caf/mailbox_element.hpp"
#include "caf/message.hpp"
#include "caf/message_id.hpp"
#include "caf/message_priority.hpp"
#include "caf/no_stages.hpp"
#include "caf/response_type.hpp"
#include "caf/system_messages.hpp"
#include "caf/is_message_sink.hpp"
#include "caf/message_priority.hpp"
#include "caf/check_typed_input.hpp"
#include "caf/typed_actor.hpp"
namespace caf {
......@@ -108,6 +110,38 @@ void anon_send(const Dest& dest, Ts&&... xs) {
std::forward<Ts>(xs)...);
}
template <message_priority P = message_priority::normal, class Dest = actor,
class Rep = int, class Period = std::ratio<1>, class... Ts>
detail::enable_if_t<!std::is_same<Dest, group>::value>
delayed_anon_send(const Dest& dest, std::chrono::duration<Rep, Period> rtime,
Ts&&... xs) {
static_assert(sizeof...(Ts) > 0, "no message to send");
using token = detail::type_list<typename detail::implicit_conversions<
typename std::decay<Ts>::type>::type...>;
static_assert(response_type_unbox<signatures_of_t<Dest>, token>::valid,
"receiver does not accept given message");
if (dest) {
auto& clock = dest->home_system().clock();
auto timeout = clock.now() + rtime;
clock.schedule_message(timeout, actor_cast<strong_actor_ptr>(dest),
make_mailbox_element(nullptr, make_message_id(P),
no_stages,
std::forward<Ts>(xs)...));
}
}
template <class Rep = int, class Period = std::ratio<1>, class... Ts>
void delayed_anon_send(const group& dest,
std::chrono::duration<Rep, Period> rtime, Ts&&... xs) {
static_assert(sizeof...(Ts) > 0, "no message to send");
if (dest) {
auto& clock = dest->system().clock();
auto timeout = clock.now() + rtime;
clock.schedule_message(timeout, dest,
make_message(std::forward<Ts>(xs)...));
}
}
/// Anonymously sends `dest` an exit message.
template <class Dest>
void anon_send_exit(const Dest& dest, exit_reason reason) {
......
......@@ -48,7 +48,11 @@ public:
return &view_;
}
inline explicit operator bool() const {
const typed_actor_view<Sigs...>* operator->() const {
return &view_;
}
explicit operator bool() const {
return static_cast<bool>(view_.internal_ptr());
}
......
......@@ -77,6 +77,10 @@ public:
return self_->system();
}
actor_system& home_system() const {
return self_->home_system();
}
void quit(exit_reason reason = exit_reason::normal) {
self_->quit(reason);
}
......
......@@ -212,7 +212,7 @@ class delayed_testee : public composable_behavior<delayed_testee_actor> {
public:
result<void> operator()(int x) override {
CAF_CHECK_EQUAL(x, 42);
self->delayed_anon_send(self, std::chrono::milliseconds(10), true);
delayed_anon_send(self, std::chrono::milliseconds(10), true);
return unit;
}
......
......@@ -57,7 +57,7 @@ timer::behavior_type timer_impl(timer::stateful_pointer<timer_state> self) {
timer::behavior_type timer_impl2(timer::pointer self) {
auto had_reset = std::make_shared<bool>(false);
self->delayed_anon_send(self, ms(100), reset_atom::value);
delayed_anon_send(self, ms(100), reset_atom::value);
return {
[=](reset_atom) {
CAF_MESSAGE("timer reset");
......
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