event/Loop: use std::chrono
This commit is contained in:
@@ -19,8 +19,6 @@
|
||||
|
||||
#include "config.h"
|
||||
#include "Loop.hxx"
|
||||
|
||||
#include "system/Clock.hxx"
|
||||
#include "TimeoutMonitor.hxx"
|
||||
#include "SocketMonitor.hxx"
|
||||
#include "IdleMonitor.hxx"
|
||||
@@ -29,8 +27,7 @@
|
||||
#include <algorithm>
|
||||
|
||||
EventLoop::EventLoop()
|
||||
:SocketMonitor(*this),
|
||||
now_ms(::MonotonicClockMS())
|
||||
:SocketMonitor(*this)
|
||||
{
|
||||
SocketMonitor::Open(wake_fd.Get());
|
||||
SocketMonitor::Schedule(SocketMonitor::READ);
|
||||
@@ -93,13 +90,13 @@ EventLoop::RemoveIdle(IdleMonitor &i)
|
||||
}
|
||||
|
||||
void
|
||||
EventLoop::AddTimer(TimeoutMonitor &t, unsigned ms)
|
||||
EventLoop::AddTimer(TimeoutMonitor &t, std::chrono::steady_clock::duration d)
|
||||
{
|
||||
/* can't use IsInsideOrVirgin() here because libavahi-client
|
||||
modifies the timeout during avahi_client_free() */
|
||||
assert(IsInsideOrNull());
|
||||
|
||||
timers.insert(TimerRecord(t, now_ms + ms));
|
||||
timers.insert(TimerRecord(t, now + d));
|
||||
again = true;
|
||||
}
|
||||
|
||||
@@ -116,6 +113,19 @@ EventLoop::CancelTimer(TimeoutMonitor &t)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given timeout specification to a milliseconds integer,
|
||||
* to be used by functions like poll() and epoll_wait(). Any negative
|
||||
* value (= never times out) is translated to the magic value -1.
|
||||
*/
|
||||
static constexpr int
|
||||
ExportTimeoutMS(std::chrono::steady_clock::duration timeout)
|
||||
{
|
||||
return timeout >= timeout.zero()
|
||||
? int(std::chrono::duration_cast<std::chrono::milliseconds>(timeout).count())
|
||||
: -1;
|
||||
}
|
||||
|
||||
void
|
||||
EventLoop::Run()
|
||||
{
|
||||
@@ -132,21 +142,21 @@ EventLoop::Run()
|
||||
assert(busy);
|
||||
|
||||
do {
|
||||
now_ms = ::MonotonicClockMS();
|
||||
now = std::chrono::steady_clock::now();
|
||||
again = false;
|
||||
|
||||
/* invoke timers */
|
||||
|
||||
int timeout_ms;
|
||||
std::chrono::steady_clock::duration timeout;
|
||||
while (true) {
|
||||
auto i = timers.begin();
|
||||
if (i == timers.end()) {
|
||||
timeout_ms = -1;
|
||||
timeout = std::chrono::steady_clock::duration(-1);
|
||||
break;
|
||||
}
|
||||
|
||||
timeout_ms = i->due_ms - now_ms;
|
||||
if (timeout_ms > 0)
|
||||
timeout = i->due - now;
|
||||
if (timeout > timeout.zero())
|
||||
break;
|
||||
|
||||
TimeoutMonitor &m = i->timer;
|
||||
@@ -185,9 +195,9 @@ EventLoop::Run()
|
||||
|
||||
/* wait for new event */
|
||||
|
||||
poll_group.ReadEvents(poll_result, timeout_ms);
|
||||
poll_group.ReadEvents(poll_result, ExportTimeoutMS(timeout));
|
||||
|
||||
now_ms = ::MonotonicClockMS();
|
||||
now = std::chrono::steady_clock::now();
|
||||
|
||||
mutex.lock();
|
||||
busy = true;
|
||||
|
@@ -29,6 +29,7 @@
|
||||
#include "WakeFD.hxx"
|
||||
#include "SocketMonitor.hxx"
|
||||
|
||||
#include <chrono>
|
||||
#include <list>
|
||||
#include <set>
|
||||
|
||||
@@ -54,20 +55,20 @@ class EventLoop final : SocketMonitor
|
||||
* Projected monotonic_clock_ms() value when this
|
||||
* timer is due.
|
||||
*/
|
||||
const unsigned due_ms;
|
||||
const std::chrono::steady_clock::time_point due;
|
||||
|
||||
TimeoutMonitor &timer;
|
||||
|
||||
constexpr TimerRecord(TimeoutMonitor &_timer,
|
||||
unsigned _due_ms)
|
||||
:due_ms(_due_ms), timer(_timer) {}
|
||||
std::chrono::steady_clock::time_point _due)
|
||||
:due(_due), timer(_timer) {}
|
||||
|
||||
bool operator<(const TimerRecord &other) const {
|
||||
return due_ms < other.due_ms;
|
||||
return due < other.due;
|
||||
}
|
||||
|
||||
bool IsDue(unsigned _now_ms) const {
|
||||
return _now_ms >= due_ms;
|
||||
bool IsDue(std::chrono::steady_clock::time_point _now) const {
|
||||
return _now >= due;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -79,7 +80,7 @@ class EventLoop final : SocketMonitor
|
||||
Mutex mutex;
|
||||
std::list<DeferredMonitor *> deferred;
|
||||
|
||||
unsigned now_ms;
|
||||
std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
|
||||
|
||||
bool quit = false;
|
||||
|
||||
@@ -118,12 +119,12 @@ public:
|
||||
~EventLoop();
|
||||
|
||||
/**
|
||||
* A caching wrapper for MonotonicClockMS().
|
||||
* A caching wrapper for std::chrono::steady_clock::now().
|
||||
*/
|
||||
unsigned GetTimeMS() const {
|
||||
std::chrono::steady_clock::time_point GetTime() const {
|
||||
assert(IsInside());
|
||||
|
||||
return now_ms;
|
||||
return now;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -157,7 +158,8 @@ public:
|
||||
void AddIdle(IdleMonitor &i);
|
||||
void RemoveIdle(IdleMonitor &i);
|
||||
|
||||
void AddTimer(TimeoutMonitor &t, unsigned ms);
|
||||
void AddTimer(TimeoutMonitor &t,
|
||||
std::chrono::steady_clock::duration d);
|
||||
void CancelTimer(TimeoutMonitor &t);
|
||||
|
||||
/**
|
||||
|
@@ -73,9 +73,9 @@ MultiSocketMonitor::ReplaceSocketList(pollfd *pfds, unsigned n)
|
||||
void
|
||||
MultiSocketMonitor::Prepare()
|
||||
{
|
||||
int timeout_ms = PrepareSockets();
|
||||
if (timeout_ms >= 0)
|
||||
TimeoutMonitor::Schedule(timeout_ms);
|
||||
const auto timeout = PrepareSockets();
|
||||
if (timeout >= timeout.zero())
|
||||
TimeoutMonitor::Schedule(timeout);
|
||||
else
|
||||
TimeoutMonitor::Cancel();
|
||||
|
||||
|
@@ -163,9 +163,9 @@ public:
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @return timeout [ms] or -1 for no timeout
|
||||
* @return timeout or a negative value for no timeout
|
||||
*/
|
||||
virtual int PrepareSockets() = 0;
|
||||
virtual std::chrono::steady_clock::duration PrepareSockets() = 0;
|
||||
virtual void DispatchSockets() = 0;
|
||||
|
||||
private:
|
||||
|
@@ -31,21 +31,12 @@ TimeoutMonitor::Cancel()
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
TimeoutMonitor::Schedule(unsigned ms)
|
||||
TimeoutMonitor::Schedule(std::chrono::steady_clock::duration d)
|
||||
{
|
||||
Cancel();
|
||||
|
||||
active = true;
|
||||
loop.AddTimer(*this, ms);
|
||||
}
|
||||
|
||||
void
|
||||
TimeoutMonitor::ScheduleSeconds(unsigned s)
|
||||
{
|
||||
Cancel();
|
||||
|
||||
Schedule(s * 1000u);
|
||||
loop.AddTimer(*this, d);
|
||||
}
|
||||
|
||||
void
|
||||
|
@@ -22,6 +22,8 @@
|
||||
|
||||
#include "check.h"
|
||||
|
||||
#include <chrono>
|
||||
|
||||
class EventLoop;
|
||||
|
||||
/**
|
||||
@@ -56,8 +58,7 @@ public:
|
||||
return active;
|
||||
}
|
||||
|
||||
void Schedule(unsigned ms);
|
||||
void ScheduleSeconds(unsigned s);
|
||||
void Schedule(std::chrono::steady_clock::duration d);
|
||||
void Cancel();
|
||||
|
||||
protected:
|
||||
|
Reference in New Issue
Block a user