tdlight/td/telegram/AlarmManager.cpp
2024-08-15 19:35:59 +03:00

59 lines
1.8 KiB
C++

//
// 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<void *>(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<AlarmManager *>(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<Unit> &&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