56 lines
1.1 KiB
C++
56 lines
1.1 KiB
C++
|
#include "Timer.hpp"
|
||
|
|
||
|
#include <sys/timerfd.h>
|
||
|
|
||
|
namespace nanosm {
|
||
|
|
||
|
Timer::Timer(nanosm::EventLoop& ev)
|
||
|
: nanosm::EventLoop::IoObject(ev) {
|
||
|
timerFd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC);
|
||
|
if(timerFd < 0)
|
||
|
perror("timerfd_create");
|
||
|
}
|
||
|
|
||
|
Timer::~Timer() {
|
||
|
Reset();
|
||
|
}
|
||
|
|
||
|
void Timer::Reset() {
|
||
|
if(timerFd != -1)
|
||
|
close(timerFd);
|
||
|
}
|
||
|
|
||
|
int Timer::GetFD() const {
|
||
|
return timerFd;
|
||
|
}
|
||
|
|
||
|
int Timer::InterestedEvents() const {
|
||
|
/// TimerFD only returns EPOLLIN.
|
||
|
return EPOLLIN;
|
||
|
}
|
||
|
|
||
|
void Timer::OnReady(int eventMask) {
|
||
|
u64 expiryCount {};
|
||
|
|
||
|
// Read the amount of timer expires so it stops screaming.
|
||
|
static_cast<void>(read(timerFd, &expiryCount, sizeof(expiryCount)));
|
||
|
|
||
|
// Post the expiry callback directly into the event loop
|
||
|
if(cb)
|
||
|
eventLoop.Post(cb);
|
||
|
}
|
||
|
|
||
|
void Timer::SetExpiryCallback(std::function<void()> expire) {
|
||
|
cb = expire;
|
||
|
}
|
||
|
|
||
|
void Timer::Arm(u32 durationSeconds) {
|
||
|
itimerspec spec {};
|
||
|
spec.it_value.tv_sec = durationSeconds;
|
||
|
|
||
|
// TODO: validate.
|
||
|
timerfd_settime(timerFd, 0, &spec, nullptr);
|
||
|
}
|
||
|
|
||
|
} // namespace nanosm
|