libos: Add Timer::reset, restart and stop

This commit is contained in:
apio 2024-01-08 19:01:59 +01:00
parent 1223c6c20b
commit 6bf8225f63
Signed by: apio
GPG Key ID: B8A7D06E42258954
2 changed files with 42 additions and 3 deletions

View File

@ -22,15 +22,21 @@ namespace os
static Result<OwnedPtr<Timer>> create_singleshot(unsigned int milliseconds, Action&& action);
static Result<OwnedPtr<Timer>> create_repeating(unsigned int milliseconds, Action&& action);
void restart();
void reset(unsigned int milliseconds);
void stop();
~Timer();
private:
timer_t m_timerid { -1 };
bool m_repeating;
bool m_stopped { false };
struct timespec m_interval;
Action m_action;
void check_if_should_invoke_action();
void readd_if_necessary();
Timer() = default;

View File

@ -54,21 +54,45 @@ namespace os
return timer;
}
void Timer::restart()
{
struct itimerspec itimer = { .it_interval = { .tv_sec = 0, .tv_nsec = 0 }, .it_value = m_interval };
timer_settime(m_timerid, 0, &itimer, nullptr);
readd_if_necessary();
}
void Timer::reset(unsigned int milliseconds)
{
m_interval = { .tv_sec = milliseconds / 1000, .tv_nsec = (milliseconds % 1000) * 1'000'000 };
restart();
}
void Timer::stop()
{
EventLoop::the().m_timer_list.remove(this);
m_stopped = true;
struct itimerspec itimer;
memset(&itimer, 0, sizeof(itimer));
timer_settime(m_timerid, 0, &itimer, nullptr);
}
void Timer::check_if_should_invoke_action()
{
struct itimerspec remaining;
if (timer_gettime(m_timerid, &remaining) < 0) return;
if (!remaining.it_value.tv_sec && !remaining.it_value.tv_nsec)
if (!remaining.it_value.tv_sec && !remaining.it_value.tv_nsec && !m_stopped)
{
// Timer expired!
m_action();
if (!m_repeating)
{
timer_delete(m_timerid);
EventLoop::the().m_timer_list.remove(this);
m_timerid = -1;
m_stopped = true;
}
else
{
@ -79,6 +103,15 @@ namespace os
}
}
void Timer::readd_if_necessary()
{
if (m_stopped)
{
m_stopped = false;
EventLoop::the().m_timer_list.append(this);
}
}
Timer::~Timer()
{
if (m_timerid >= 0) timer_delete(m_timerid);