SecureValueRecovery2/enclave/timeout/timeout.cc

60 lines
1.8 KiB
C++

// Copyright 2023 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
#include "timeout/timeout.h"
#include "metrics/metrics.h"
namespace svr2::timeout {
Timeout::Timeout() : ticks_(0), timeout_cancel_gen_(0) {}
void Timeout::TimerTick(context::Context* ctx) {
ACQUIRE_NAMED_LOCK(lock, mu_, ctx, lock_timeout);
MEASURE_CPU(ctx, cpu_timeout_timer_tick);
ticks_++;
auto timeouts_to_run = timeouts_.find(ticks_);
if (timeouts_to_run == timeouts_.end()) {
return;
}
TimeoutSet ts = std::move(timeouts_to_run->second);
timeouts_.erase(timeouts_to_run);
// We unlock before calling timeout methods, since they may want to do things
// that also create timeouts.
lock.unlock();
for (auto iter = ts.begin(); iter != ts.end(); ++iter) {
COUNTER(timeout, timeouts_run)->Increment();
iter->second(ctx);
}
}
Cancel Timeout::SetTimeout(context::Context* ctx, util::Ticks ticks_from_now, std::function<void(context::Context*)> fn) {
ACQUIRE_LOCK(mu_, ctx, lock_timeout);
CHECK(ticks_from_now + ticks_ > ticks_);
Cancel tc(ticks_from_now + ticks_, ++timeout_cancel_gen_);
auto finder = timeouts_.find(tc.at_tick_);
if (finder == timeouts_.end()) {
auto [i, b] = timeouts_.emplace(
tc.at_tick_,
std::unordered_map<int64_t, std::function<void(context::Context*)>>());
finder = i;
}
finder->second[tc.cancel_id_] = fn;
COUNTER(timeout, timeouts_created)->Increment();
return tc;
}
void Timeout::CancelTimeout(context::Context* ctx, const Cancel& tc) {
ACQUIRE_LOCK(mu_, ctx, lock_timeout);
auto finder = timeouts_.find(tc.at_tick_);
if (finder != timeouts_.end()) {
auto f2 = finder->second.find(tc.cancel_id_);
if (f2 != finder->second.end()) {
COUNTER(timeout, timeouts_cancelled)->Increment();
finder->second.erase(f2);
}
}
}
} // namespace svr2::timeout