Commit 4ef3a353 authored by Dominik Charousset's avatar Dominik Charousset

Return void from deliver and support unit_t

parent 3fda40a8
...@@ -54,10 +54,10 @@ public: ...@@ -54,10 +54,10 @@ public:
/// Satisfies the promise by sending a non-error response message. /// Satisfies the promise by sending a non-error response message.
template <class T, class... Ts> template <class T, class... Ts>
detail::enable_if_t< detail::enable_if_t<((sizeof...(Ts) > 0)
((sizeof...(Ts) > 0) || !std::is_convertible<T, error>::value) || (!std::is_convertible<T, error>::value
&& !detail::is_expected<detail::decay_t<T>>::value, && !std::is_same<detail::decay_t<T>, unit_t>::value))
response_promise> && !detail::is_expected<detail::decay_t<T>>::value>
deliver(T&& x, Ts&&... xs) { deliver(T&& x, Ts&&... xs) {
using ts = detail::type_list<detail::decay_t<T>, detail::decay_t<Ts>...>; using ts = detail::type_list<detail::decay_t<T>, detail::decay_t<Ts>...>;
static_assert(!detail::tl_exists<ts, detail::is_result>::value, static_assert(!detail::tl_exists<ts, detail::is_result>::value,
...@@ -69,7 +69,7 @@ public: ...@@ -69,7 +69,7 @@ public:
} }
template <class T> template <class T>
response_promise deliver(expected<T> x) { void deliver(expected<T> x) {
if (x) if (x)
return deliver(std::move(*x)); return deliver(std::move(*x));
return deliver(std::move(x.error())); return deliver(std::move(x.error()));
...@@ -102,15 +102,18 @@ public: ...@@ -102,15 +102,18 @@ public:
} }
/// Satisfies the promise by sending an error response message. /// Satisfies the promise by sending an error response message.
/// For non-requests, nothing is done. void deliver(error x);
response_promise deliver(error x);
/// Satisfies the promise by sending an empty message if this promise has a
/// valid message ID, i.e., `async() == false`.
void deliver(unit_t x);
/// Returns whether this response promise replies to an asynchronous message. /// Returns whether this response promise replies to an asynchronous message.
bool async() const; bool async() const;
/// Queries whether this promise is a valid promise that is not satisfied yet. /// Queries whether this promise is a valid promise that is not satisfied yet.
inline bool pending() const { inline bool pending() const {
return !stages_.empty() || source_; return source_ != nullptr || !stages_.empty();
} }
/// Returns the source of the corresponding request. /// Returns the source of the corresponding request.
...@@ -123,6 +126,12 @@ public: ...@@ -123,6 +126,12 @@ public:
return stages_; return stages_;
} }
/// Returns the actor that will receive the response, i.e.,
/// `stages().front()` if `!stages().empty()` or `source()` otherwise.
inline strong_actor_ptr next() const {
return stages_.empty() ? source_ : stages_.front();
}
/// Returns the message ID of the corresponding request. /// Returns the message ID of the corresponding request.
inline message_id id() const { inline message_id id() const {
return id_; return id_;
...@@ -131,7 +140,7 @@ public: ...@@ -131,7 +140,7 @@ public:
private: private:
execution_unit* context(); execution_unit* context();
response_promise deliver_impl(message msg); void deliver_impl(message msg);
strong_actor_ptr self_; strong_actor_ptr self_;
strong_actor_ptr source_; strong_actor_ptr source_;
......
...@@ -55,9 +55,13 @@ response_promise::response_promise(strong_actor_ptr self, mailbox_element& src) ...@@ -55,9 +55,13 @@ response_promise::response_promise(strong_actor_ptr self, mailbox_element& src)
// nop // nop
} }
response_promise response_promise::deliver(error x) { void response_promise::deliver(error x) {
//if (id_.valid()) deliver_impl(make_message(std::move(x)));
return deliver_impl(make_message(std::move(x))); }
void response_promise::deliver(unit_t) {
if (id_.valid())
deliver_impl(make_message());
} }
bool response_promise::async() const { bool response_promise::async() const {
...@@ -72,26 +76,24 @@ execution_unit* response_promise::context() { ...@@ -72,26 +76,24 @@ execution_unit* response_promise::context() {
->context(); ->context();
} }
response_promise response_promise::deliver_impl(message msg) { void response_promise::deliver_impl(message msg) {
CAF_LOG_TRACE(CAF_ARG(msg));
if (!stages_.empty()) { if (!stages_.empty()) {
auto next = std::move(stages_.back()); auto next = std::move(stages_.back());
stages_.pop_back(); stages_.pop_back();
next->enqueue(make_mailbox_element(std::move(source_), id_, next->enqueue(make_mailbox_element(std::move(source_), id_,
std::move(stages_), std::move(msg)), std::move(stages_), std::move(msg)),
context()); context());
return *this; return;
} }
if (source_) { if (source_) {
source_->enqueue(std::move(self_), id_.response_id(), source_->enqueue(std::move(self_), id_.response_id(),
std::move(msg), context()); std::move(msg), context());
source_.reset(); source_.reset();
return *this; return;
} }
if (self_) CAF_LOG_INFO_IF(self_ != nullptr, "response promise already satisfied");
CAF_LOG_INFO("response promise already satisfied"); CAF_LOG_INFO_IF(self_ == nullptr, "invalid response promise");
else
CAF_LOG_INFO("invalid response promise");
return *this;
} }
} // namespace caf } // namespace caf
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