2024-08-15 17:26:01 +02:00
|
|
|
//
|
|
|
|
// 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"
|
|
|
|
|
2024-08-15 17:49:24 +02:00
|
|
|
#include "td/telegram/Global.h"
|
|
|
|
|
2024-08-15 18:35:59 +02:00
|
|
|
#include "td/utils/Status.h"
|
|
|
|
|
2024-08-15 17:26:01 +02:00
|
|
|
namespace td {
|
|
|
|
|
|
|
|
AlarmManager::AlarmManager(ActorShared<> parent) : parent_(std::move(parent)) {
|
2024-08-15 17:49:24 +02:00
|
|
|
alarm_timeout_.set_callback(on_alarm_timeout_callback);
|
|
|
|
alarm_timeout_.set_callback_data(static_cast<void *>(this));
|
2024-08-15 17:26:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void AlarmManager::tear_down() {
|
2024-08-15 17:49:24 +02:00
|
|
|
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);
|
|
|
|
}
|
2024-08-15 17:26:01 +02:00
|
|
|
parent_.reset();
|
|
|
|
}
|
|
|
|
|
2024-08-15 17:49:24 +02:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2024-08-15 17:26:01 +02:00
|
|
|
} // namespace td
|