// // Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // 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/telegram/AlarmManager.h" #include "td/telegram/Global.h" #include "td/utils/Status.h" namespace td { AlarmManager::AlarmManager(ActorShared<> parent) : parent_(std::move(parent)) { alarm_timeout_.set_callback(on_alarm_timeout_callback); alarm_timeout_.set_callback_data(static_cast(this)); } void AlarmManager::tear_down() { while (!pending_alarms_.empty()) { auto it = pending_alarms_.begin(); auto alarm_id = it->first; auto promise = std::move(it->second); pending_alarms_.erase(it); promise.set_error(G()->request_aborted_error()); alarm_timeout_.cancel_timeout(alarm_id); } parent_.reset(); } void AlarmManager::on_alarm_timeout_callback(void *alarm_manager_ptr, int64 alarm_id) { auto alarm_manager = static_cast(alarm_manager_ptr); auto alarm_manager_id = alarm_manager->actor_id(alarm_manager); send_closure_later(alarm_manager_id, &AlarmManager::on_alarm_timeout, alarm_id); } void AlarmManager::on_alarm_timeout(int64 alarm_id) { auto it = pending_alarms_.find(alarm_id); if (it == pending_alarms_.end()) { return; } auto promise = std::move(it->second); pending_alarms_.erase(alarm_id); promise.set_value(Unit()); } void AlarmManager::set_alarm(double seconds, Promise &&promise) { if (seconds < 0 || seconds > 3e9) { return promise.set_error(Status::Error(400, "Wrong parameter seconds specified")); } auto alarm_id = alarm_id_++; pending_alarms_.emplace(alarm_id, std::move(promise)); alarm_timeout_.set_timeout_in(alarm_id, seconds); } } // namespace td