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_singleshot(unsigned int milliseconds, Action&& action);
|
||||||
static Result<OwnedPtr<Timer>> create_repeating(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();
|
~Timer();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
timer_t m_timerid { -1 };
|
timer_t m_timerid { -1 };
|
||||||
bool m_repeating;
|
bool m_repeating;
|
||||||
|
bool m_stopped { false };
|
||||||
struct timespec m_interval;
|
struct timespec m_interval;
|
||||||
Action m_action;
|
Action m_action;
|
||||||
|
|
||||||
void check_if_should_invoke_action();
|
void check_if_should_invoke_action();
|
||||||
|
void readd_if_necessary();
|
||||||
|
|
||||||
Timer() = default;
|
Timer() = default;
|
||||||
|
|
||||||
|
@ -54,21 +54,45 @@ namespace os
|
|||||||
return timer;
|
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()
|
void Timer::check_if_should_invoke_action()
|
||||||
{
|
{
|
||||||
struct itimerspec remaining;
|
struct itimerspec remaining;
|
||||||
if (timer_gettime(m_timerid, &remaining) < 0) return;
|
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!
|
// Timer expired!
|
||||||
m_action();
|
m_action();
|
||||||
|
|
||||||
if (!m_repeating)
|
if (!m_repeating)
|
||||||
{
|
{
|
||||||
timer_delete(m_timerid);
|
|
||||||
EventLoop::the().m_timer_list.remove(this);
|
EventLoop::the().m_timer_list.remove(this);
|
||||||
m_timerid = -1;
|
m_stopped = true;
|
||||||
}
|
}
|
||||||
else
|
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()
|
Timer::~Timer()
|
||||||
{
|
{
|
||||||
if (m_timerid >= 0) timer_delete(m_timerid);
|
if (m_timerid >= 0) timer_delete(m_timerid);
|
||||||
|
Loading…
Reference in New Issue
Block a user