Commit 0777157c authored by Dominik Charousset's avatar Dominik Charousset

Fix unexpected responses to anon_send, close #1046

parent 2d78dbd6
......@@ -46,17 +46,22 @@ void profiled_send(Self* self, Sender&& sender, const Handle& receiver,
}
template <class Self, class Sender, class Handle, class... Ts>
void profiled_send(Self* self, Sender&& sender, const Handle& receiver,
void profiled_send(Self* self, Sender&& sender, const Handle& dst,
actor_clock& clock, actor_clock::time_point timeout,
message_id msg_id, Ts&&... xs) {
CAF_IGNORE_UNUSED(self);
if (receiver) {
if (dst) {
if constexpr (std::is_same<Handle, group>::value) {
clock.schedule_message(timeout, dst, std::forward<Sender>(sender),
make_message(std::forward<Ts>(xs)...));
} else {
auto element = make_mailbox_element(std::forward<Sender>(sender), msg_id,
no_stages, std::forward<Ts>(xs)...);
CAF_BEFORE_SENDING_SCHEDULED(self, timeout, *element);
clock.schedule_message(timeout, actor_cast<strong_actor_ptr>(receiver),
clock.schedule_message(timeout, actor_cast<strong_actor_ptr>(dst),
std::move(element));
}
}
}
} // namespace caf::detail
......@@ -94,7 +94,7 @@ public:
static_assert(response_type_unbox<signatures_of_t<Dest>, token>::valid,
"receiver does not accept given message");
auto self = dptr();
detail::profiled_send(self, self->ctrl(), dest, make_message_id(P), {},
detail::profiled_send(self, nullptr, dest, make_message_id(P), {},
self->context(), std::forward<Ts>(xs)...);
}
......@@ -172,8 +172,8 @@ public:
detail::type_list<detail::strip_and_convert_t<Ts>...> args_token;
type_check(dest, args_token);
auto self = dptr();
detail::profiled_send(self, self->ctrl(), dest, self->system().clock(),
timeout, make_message_id(P), std::forward<Ts>(xs)...);
detail::profiled_send(self, nullptr, dest, self->system().clock(), timeout,
make_message_id(P), std::forward<Ts>(xs)...);
}
template <message_priority P = message_priority::normal, class Dest = actor,
......@@ -187,40 +187,11 @@ public:
auto self = dptr();
auto& clock = self->system().clock();
auto timeout = clock.now() + rel_timeout;
detail::profiled_send(self, self->ctrl(), dest, clock, timeout,
detail::profiled_send(self, nullptr, dest, clock, timeout,
make_message_id(P), 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) {
delayed_anon_send_impl(dest, rtime, std::forward<Ts>(xs)...);
}
private:
template <class Dest, class... Ts>
void scheduled_send_impl(message_id mid, const Dest& dest, actor_clock& clock,
actor_clock::time_point timeout, Ts&&... xs) {
static_assert(sizeof...(Ts) > 0, "no message to send");
detail::type_list<detail::strip_and_convert_t<Ts>...> args_token;
type_check(dest, args_token);
auto self = dptr();
detail::profiled_send(self, self->ctrl(), dest, clock, timeout, mid,
std::forward<Ts>(xs)...);
}
template <class Dest, class... Ts>
void
scheduled_anon_send_impl(message_id mid, const Dest& dest, actor_clock& clock,
actor_clock::time_point timeout, Ts&&... xs) {
static_assert(sizeof...(Ts) > 0, "no message to send");
detail::type_list<detail::strip_and_convert_t<Ts>...> args_token;
type_check(dest, args_token);
auto self = dptr();
detail::profiled_send(self, nullptr, dest, clock, timeout, mid,
std::forward<Ts>(xs)...);
}
template <class Dest, class ArgTypes>
static void type_check(const Dest&, ArgTypes) {
static_assert(!statically_typed<Subtype>() || statically_typed<Dest>(),
......
......@@ -31,7 +31,7 @@ using std::chrono::seconds;
namespace {
behavior testee_impl(event_based_actor* self) {
self->set_default_handler(drop);
self->set_default_handler(reflect);
return {[] {
// nop
}};
......@@ -55,28 +55,50 @@ struct fixture : test_coordinator_fixture<> {
CAF_TEST_FIXTURE_SCOPE(sender_tests, fixture)
CAF_TEST(delayed actor message) {
CAF_TEST(delayed actor messages receive responses) {
self->delayed_send(testee, seconds(1), "hello world");
sched.trigger_timeout();
expect((std::string), from(self).to(testee).with("hello world"));
expect((std::string), from(testee).to(self).with("hello world"));
self->scheduled_send(testee, self->clock().now() + seconds(1), "hello world");
sched.trigger_timeout();
expect((std::string), from(self).to(testee).with("hello world"));
expect((std::string), from(testee).to(self).with("hello world"));
}
CAF_TEST(delayed group message) {
CAF_TEST(delayed group message receive responses) {
self->delayed_send(grp, seconds(1), "hello world");
sched.trigger_timeout();
expect((std::string), from(self).to(testee).with("hello world"));
}
CAF_TEST(scheduled actor message) {
self->scheduled_send(testee, self->clock().now() + seconds(1), "hello world");
expect((std::string), from(testee).to(self).with("hello world"));
self->scheduled_send(grp, self->clock().now() + seconds(1), "hello world");
sched.trigger_timeout();
expect((std::string), from(self).to(testee).with("hello world"));
expect((std::string), from(testee).to(self).with("hello world"));
}
CAF_TEST(scheduled group message) {
self->scheduled_send(grp, self->clock().now() + seconds(1), "hello world");
CAF_TEST(anonymous messages receive no response) {
self->anon_send(testee, "hello world");
expect((std::string), to(testee).with("hello world"));
disallow((std::string), from(testee).to(self).with("hello world"));
self->delayed_anon_send(testee, seconds(1), "hello world");
sched.trigger_timeout();
expect((std::string), from(self).to(testee).with("hello world"));
expect((std::string), to(testee).with("hello world"));
disallow((std::string), from(testee).to(self).with("hello world"));
self->scheduled_anon_send(testee, self->clock().now() + seconds(1),
"hello world");
sched.trigger_timeout();
expect((std::string), to(testee).with("hello world"));
disallow((std::string), from(testee).to(self).with("hello world"));
self->delayed_anon_send(grp, seconds(1), "hello world");
sched.trigger_timeout();
expect((std::string), to(testee).with("hello world"));
disallow((std::string), from(testee).to(self).with("hello world"));
self->scheduled_anon_send(grp, self->clock().now() + seconds(1),
"hello world");
sched.trigger_timeout();
expect((std::string), to(testee).with("hello world"));
disallow((std::string), from(testee).to(self).with("hello world"));
}
CAF_TEST_FIXTURE_SCOPE_END()
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