Commit be404167 authored by Dominik Charousset's avatar Dominik Charousset

Support more than scheduled_actor in testing DSL

parent 3c9ca018
...@@ -112,6 +112,13 @@ public: ...@@ -112,6 +112,13 @@ public:
/// @cond PRIVATE /// @cond PRIVATE
/// Called by the testing DSL to peek at the next element in the mailbox. Do
/// not call this function in production code! The default implementation
/// always returns `nullptr`.
/// @returns A pointer to the next mailbox element or `nullptr` if the
/// mailbox is empty or the actor does not have a mailbox.
virtual mailbox_element* peek_at_next_mailbox_element();
template <class... Ts> template <class... Ts>
void eq_impl(message_id mid, strong_actor_ptr sender, void eq_impl(message_id mid, strong_actor_ptr sender,
execution_unit* ctx, Ts&&... xs) { execution_unit* ctx, Ts&&... xs) {
......
...@@ -244,6 +244,8 @@ public: ...@@ -244,6 +244,8 @@ public:
void enqueue(mailbox_element_ptr, execution_unit*) override; void enqueue(mailbox_element_ptr, execution_unit*) override;
mailbox_element* peek_at_next_mailbox_element() override;
// -- overridden functions of local_actor ------------------------------------ // -- overridden functions of local_actor ------------------------------------
const char* name() const override; const char* name() const override;
......
...@@ -262,6 +262,8 @@ public: ...@@ -262,6 +262,8 @@ public:
void enqueue(mailbox_element_ptr ptr, execution_unit* eu) override; void enqueue(mailbox_element_ptr ptr, execution_unit* eu) override;
mailbox_element* peek_at_next_mailbox_element() override;
// -- overridden functions of local_actor ------------------------------------ // -- overridden functions of local_actor ------------------------------------
const char* name() const override; const char* name() const override;
......
...@@ -90,6 +90,10 @@ actor_system& abstract_actor::home_system() const noexcept { ...@@ -90,6 +90,10 @@ actor_system& abstract_actor::home_system() const noexcept {
return *(actor_control_block::from(this)->home_system); return *(actor_control_block::from(this)->home_system);
} }
mailbox_element* abstract_actor::peek_at_next_mailbox_element() {
return nullptr;
}
void abstract_actor::register_at_system() { void abstract_actor::register_at_system() {
if (getf(is_registered_flag)) if (getf(is_registered_flag))
return; return;
......
...@@ -79,6 +79,10 @@ void blocking_actor::enqueue(mailbox_element_ptr ptr, execution_unit*) { ...@@ -79,6 +79,10 @@ void blocking_actor::enqueue(mailbox_element_ptr ptr, execution_unit*) {
} }
} }
mailbox_element* blocking_actor::peek_at_next_mailbox_element() {
return mailbox().closed() || mailbox().blocked() ? nullptr : mailbox().peek();
}
const char* blocking_actor::name() const { const char* blocking_actor::name() const {
return "blocking_actor"; return "blocking_actor";
} }
......
...@@ -187,6 +187,9 @@ void scheduled_actor::enqueue(mailbox_element_ptr ptr, execution_unit* eu) { ...@@ -187,6 +187,9 @@ void scheduled_actor::enqueue(mailbox_element_ptr ptr, execution_unit* eu) {
break; break;
} }
} }
mailbox_element* scheduled_actor::peek_at_next_mailbox_element() {
return mailbox().closed() || mailbox().blocked() ? nullptr : mailbox().peek();
}
// -- overridden functions of local_actor -------------------------------------- // -- overridden functions of local_actor --------------------------------------
......
...@@ -191,6 +191,10 @@ public: ...@@ -191,6 +191,10 @@ public:
return ptr_; return ptr_;
} }
pointer operator->() const {
return get();
}
ptrdiff_t compare(const caf_handle& other) const { ptrdiff_t compare(const caf_handle& other) const {
return reinterpret_cast<ptrdiff_t>(ptr_) return reinterpret_cast<ptrdiff_t>(ptr_)
- reinterpret_cast<ptrdiff_t>(other.ptr_); - reinterpret_cast<ptrdiff_t>(other.ptr_);
...@@ -204,32 +208,12 @@ private: ...@@ -204,32 +208,12 @@ private:
caf::abstract_actor* ptr_; caf::abstract_actor* ptr_;
}; };
// -- access to an actor's mailbox ---------------------------------------------
/// Returns a pointer to the next element in an actor's mailbox without taking
/// it out of the mailbox.
/// @pre `ptr` is alive and either a `scheduled_actor` or `blocking_actor`
inline caf::mailbox_element* next_mailbox_element(caf_handle x) {
CAF_ASSERT(x.get() != nullptr);
auto sptr = dynamic_cast<caf::scheduled_actor*>(x.get());
if (sptr != nullptr) {
return sptr->mailbox().closed() || sptr->mailbox().blocked()
? nullptr
: sptr->mailbox().peek();
}
auto bptr = dynamic_cast<caf::blocking_actor*>(x.get());
CAF_ASSERT(bptr != nullptr);
return bptr->mailbox().closed() || bptr->mailbox().blocked()
? nullptr
: bptr->mailbox().peek();
}
// -- introspection of the next mailbox element -------------------------------- // -- introspection of the next mailbox element --------------------------------
/// @private /// @private
template <class... Ts> template <class... Ts>
caf::optional<std::tuple<Ts...>> default_extract(caf_handle x) { caf::optional<std::tuple<Ts...>> default_extract(caf_handle x) {
auto ptr = next_mailbox_element(x); auto ptr = x->peek_at_next_mailbox_element();
if (ptr == nullptr || !ptr->content().template match_elements<Ts...>()) if (ptr == nullptr || !ptr->content().template match_elements<Ts...>())
return caf::none; return caf::none;
return ptr->content().template get_as_tuple<Ts...>(); return ptr->content().template get_as_tuple<Ts...>();
...@@ -277,7 +261,7 @@ template <class T, class... Ts> ...@@ -277,7 +261,7 @@ template <class T, class... Ts>
std::tuple<T, Ts...> extract(caf_handle x) { std::tuple<T, Ts...> extract(caf_handle x) {
auto result = try_extract<T, Ts...>(x); auto result = try_extract<T, Ts...>(x);
if (result == caf::none) { if (result == caf::none) {
auto ptr = next_mailbox_element(x); auto ptr = x->peek_at_next_mailbox_element();
if (ptr == nullptr) if (ptr == nullptr)
CAF_FAIL("Mailbox is empty"); CAF_FAIL("Mailbox is empty");
CAF_FAIL("Message does not match expected pattern: " CAF_FAIL("Message does not match expected pattern: "
...@@ -326,8 +310,8 @@ public: ...@@ -326,8 +310,8 @@ public:
template <class Handle> template <class Handle>
expect_clause& to(const Handle& whom) { expect_clause& to(const Handle& whom) {
CAF_REQUIRE(sched_.prioritize(whom)); CAF_REQUIRE(sched_.prioritize(whom));
dest_ = &sched_.next_job<caf::scheduled_actor>(); dest_ = &sched_.next_job<caf::abstract_actor>();
auto ptr = next_mailbox_element(dest_); auto ptr = dest_->peek_at_next_mailbox_element();
CAF_REQUIRE(ptr != nullptr); CAF_REQUIRE(ptr != nullptr);
if (src_) if (src_)
CAF_REQUIRE_EQUAL(ptr->sender, src_); CAF_REQUIRE_EQUAL(ptr->sender, src_);
...@@ -366,7 +350,7 @@ protected: ...@@ -366,7 +350,7 @@ protected:
caf::scheduler::test_coordinator& sched_; caf::scheduler::test_coordinator& sched_;
caf::strong_actor_ptr src_; caf::strong_actor_ptr src_;
caf::local_actor* dest_; caf::abstract_actor* dest_;
std::function<void ()> peek_; std::function<void ()> peek_;
}; };
...@@ -402,7 +386,7 @@ public: ...@@ -402,7 +386,7 @@ public:
template <class Handle> template <class Handle>
allow_clause& to(const Handle& whom) { allow_clause& to(const Handle& whom) {
if (sched_.prioritize(whom)) if (sched_.prioritize(whom))
dest_ = &sched_.next_job<caf::scheduled_actor>(); dest_ = &sched_.next_job<caf::abstract_actor>();
return *this; return *this;
} }
...@@ -448,7 +432,7 @@ protected: ...@@ -448,7 +432,7 @@ protected:
caf::scheduler::test_coordinator& sched_; caf::scheduler::test_coordinator& sched_;
caf::strong_actor_ptr src_; caf::strong_actor_ptr src_;
caf::local_actor* dest_; caf::abstract_actor* dest_;
std::function<bool ()> peek_; std::function<bool ()> peek_;
}; };
...@@ -457,7 +441,7 @@ class disallow_clause { ...@@ -457,7 +441,7 @@ class disallow_clause {
public: public:
disallow_clause() { disallow_clause() {
check_ = [=] { check_ = [=] {
auto ptr = next_mailbox_element(dest_); auto ptr = dest_->peek_at_next_mailbox_element();
if (ptr == nullptr) if (ptr == nullptr)
return; return;
if (src_ != nullptr && ptr->sender != src_) if (src_ != nullptr && ptr->sender != src_)
...@@ -494,7 +478,7 @@ public: ...@@ -494,7 +478,7 @@ public:
// TODO: move tmp into lambda when switching to C++14 // TODO: move tmp into lambda when switching to C++14
auto tmp = std::make_tuple(std::forward<Us>(xs)...); auto tmp = std::make_tuple(std::forward<Us>(xs)...);
check_ = [=] { check_ = [=] {
auto ptr = next_mailbox_element(dest_); auto ptr = dest_->peek_at_next_mailbox_element();
if (ptr == nullptr) if (ptr == nullptr)
return; return;
if (src_ != nullptr && ptr->sender != src_) if (src_ != nullptr && ptr->sender != src_)
......
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