diff --git a/td/telegram/Requests.h b/td/telegram/Requests.h index 5260e6ce8..0df4cbec0 100644 --- a/td/telegram/Requests.h +++ b/td/telegram/Requests.h @@ -50,14 +50,43 @@ class Requests { std::shared_ptr download_file_callback_; template - Promise create_request_promise(uint64 id) { - return PromiseCreator::lambda([actor_id = td_actor_, id](Result r_state) { - if (r_state.is_error()) { - send_closure(actor_id, &Td::send_error, id, r_state.move_as_error()); - } else { - send_closure(actor_id, &Td::send_result, id, r_state.move_as_ok()); + class RequestPromise : public PromiseInterface { + enum class State : int32 { Empty, Ready, Complete }; + ActorId td_actor_; + uint64 request_id_; + MovableValue state_{State::Empty}; + + public: + void set_value(T &&value) override { + CHECK(state_.get() == State::Ready); + send_closure(td_actor_, &Td::send_result, request_id_, std::move(value)); + state_ = State::Complete; + } + + void set_error(Status &&error) override { + if (state_.get() == State::Ready) { + send_closure(td_actor_, &Td::send_error, request_id_, std::move(error)); + state_ = State::Complete; } - }); + } + RequestPromise(const RequestPromise &) = delete; + RequestPromise &operator=(const RequestPromise &) = delete; + RequestPromise(RequestPromise &&) = default; + RequestPromise &operator=(RequestPromise &&) = default; + ~RequestPromise() override { + if (state_.get() == State::Ready) { + send_closure(td_actor_, &Td::send_error, request_id_, Status::Error("Lost promise")); + } + } + + RequestPromise(ActorId td_actor, uint64 request_id) + : td_actor_(std::move(td_actor)), request_id_(request_id), state_(State::Ready) { + } + }; + + template + Promise create_request_promise(uint64 request_id) const { + return Promise(td::make_unique>(td_actor_, request_id)); } Promise create_ok_request_promise(uint64 id);