libos: Add Timer::reset, restart and stop
This commit is contained in:
parent
1223c6c20b
commit
6bf8225f63
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user