71d03f39c3
GitOrigin-RevId: 318483224ad6164d9966f731d60cde37039bb2d4
91 lines
2.5 KiB
C++
91 lines
2.5 KiB
C++
//
|
|
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2017
|
|
//
|
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
//
|
|
#include "td/actor/MultiPromise.h"
|
|
|
|
namespace td {
|
|
void MultiPromiseActor::add_promise(Promise<Unit> &&promise) {
|
|
promises_.emplace_back(std::move(promise));
|
|
}
|
|
|
|
Promise<Unit> MultiPromiseActor::get_promise() {
|
|
if (empty()) {
|
|
register_actor("MultiPromise", this).release();
|
|
}
|
|
CHECK(!promises_.empty());
|
|
|
|
PromiseActor<Unit> promise;
|
|
FutureActor<Unit> future;
|
|
init_promise_future(&promise, &future);
|
|
|
|
future.set_event(EventCreator::raw(actor_id(), nullptr));
|
|
futures_.emplace_back(std::move(future));
|
|
return PromiseCreator::from_promise_actor(std::move(promise));
|
|
}
|
|
|
|
void MultiPromiseActor::raw_event(const Event::Raw &event) {
|
|
received_results_++;
|
|
if (received_results_ == futures_.size()) {
|
|
if (!ignore_errors_) {
|
|
for (auto &future : futures_) {
|
|
auto result = future.move_as_result();
|
|
if (result.is_error()) {
|
|
return set_result(result.move_as_error());
|
|
}
|
|
}
|
|
}
|
|
return set_result(Unit());
|
|
}
|
|
}
|
|
|
|
void MultiPromiseActor::set_ignore_errors(bool ignore_errors) {
|
|
ignore_errors_ = ignore_errors;
|
|
}
|
|
|
|
void MultiPromiseActor::set_result(Result<Unit> &&result) {
|
|
// MultiPromiseActor should be cleared before he begins to send out result
|
|
auto promises_copy = std::move(promises_);
|
|
promises_.clear();
|
|
auto futures_copy = std::move(futures_);
|
|
futures_.clear();
|
|
received_results_ = 0;
|
|
stop();
|
|
|
|
if (!promises_copy.empty()) {
|
|
for (size_t i = 0; i + 1 < promises_copy.size(); i++) {
|
|
promises_copy[i].set_result(result.clone());
|
|
}
|
|
promises_copy.back().set_result(std::move(result));
|
|
}
|
|
}
|
|
|
|
size_t MultiPromiseActor::promise_count() const {
|
|
return promises_.size();
|
|
}
|
|
|
|
void MultiPromiseActorSafe::add_promise(Promise<Unit> &&promise) {
|
|
multi_promise_->add_promise(std::move(promise));
|
|
}
|
|
|
|
Promise<Unit> MultiPromiseActorSafe::get_promise() {
|
|
return multi_promise_->get_promise();
|
|
}
|
|
|
|
void MultiPromiseActorSafe::set_ignore_errors(bool ignore_errors) {
|
|
multi_promise_->set_ignore_errors(ignore_errors);
|
|
}
|
|
|
|
size_t MultiPromiseActorSafe::promise_count() const {
|
|
return multi_promise_->promise_count();
|
|
}
|
|
|
|
MultiPromiseActorSafe::~MultiPromiseActorSafe() {
|
|
if (!multi_promise_->empty()) {
|
|
register_existing_actor(std::move(multi_promise_)).release();
|
|
}
|
|
}
|
|
} // namespace td
|