Fix timerfd_manager triggering of multiple times at the same time
parent
cdccc23aff
commit
01dd3ef89e
|
@ -80,6 +80,7 @@ void timerfd_manager_t::clear_timer(int timer_id)
|
||||||
|
|
||||||
void timerfd_manager_t::set_nearest()
|
void timerfd_manager_t::set_nearest()
|
||||||
{
|
{
|
||||||
|
again:
|
||||||
if (!timers.size())
|
if (!timers.size())
|
||||||
{
|
{
|
||||||
nearest = -1;
|
nearest = -1;
|
||||||
|
@ -115,6 +116,12 @@ void timerfd_manager_t::set_nearest()
|
||||||
exp.it_value.tv_sec--;
|
exp.it_value.tv_sec--;
|
||||||
exp.it_value.tv_nsec += 1000000000;
|
exp.it_value.tv_nsec += 1000000000;
|
||||||
}
|
}
|
||||||
|
if (exp.it_value.tv_sec < 0 || !exp.it_value.tv_sec && !exp.it_value.tv_nsec)
|
||||||
|
{
|
||||||
|
// It already happened
|
||||||
|
trigger_nearest();
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
if (timerfd_settime(timerfd, 0, &exp, NULL))
|
if (timerfd_settime(timerfd, 0, &exp, NULL))
|
||||||
{
|
{
|
||||||
throw std::runtime_error(std::string("timerfd_settime: ") + strerror(errno));
|
throw std::runtime_error(std::string("timerfd_settime: ") + strerror(errno));
|
||||||
|
@ -128,6 +135,14 @@ void timerfd_manager_t::handle_readable()
|
||||||
uint64_t n;
|
uint64_t n;
|
||||||
size_t res = read(timerfd, &n, 8);
|
size_t res = read(timerfd, &n, 8);
|
||||||
if (res == 8 && nearest >= 0)
|
if (res == 8 && nearest >= 0)
|
||||||
|
{
|
||||||
|
trigger_nearest();
|
||||||
|
}
|
||||||
|
wait_state = 0;
|
||||||
|
set_nearest();
|
||||||
|
}
|
||||||
|
|
||||||
|
void timerfd_manager_t::trigger_nearest()
|
||||||
{
|
{
|
||||||
int nearest_id = timers[nearest].id;
|
int nearest_id = timers[nearest].id;
|
||||||
auto cb = timers[nearest].callback;
|
auto cb = timers[nearest].callback;
|
||||||
|
@ -142,6 +157,3 @@ void timerfd_manager_t::handle_readable()
|
||||||
cb(nearest_id);
|
cb(nearest_id);
|
||||||
nearest = -1;
|
nearest = -1;
|
||||||
}
|
}
|
||||||
wait_state = 0;
|
|
||||||
set_nearest();
|
|
||||||
}
|
|
||||||
|
|
|
@ -23,6 +23,8 @@ class timerfd_manager_t
|
||||||
|
|
||||||
void inc_timer(timerfd_timer_t & t);
|
void inc_timer(timerfd_timer_t & t);
|
||||||
void set_nearest();
|
void set_nearest();
|
||||||
|
void trigger_nearest();
|
||||||
|
void handle_readable();
|
||||||
public:
|
public:
|
||||||
std::function<void(int, std::function<void(int, int)>)> set_fd_handler;
|
std::function<void(int, std::function<void(int, int)>)> set_fd_handler;
|
||||||
|
|
||||||
|
@ -30,5 +32,4 @@ public:
|
||||||
~timerfd_manager_t();
|
~timerfd_manager_t();
|
||||||
int set_timer(uint64_t millis, bool repeat, std::function<void(int)> callback);
|
int set_timer(uint64_t millis, bool repeat, std::function<void(int)> callback);
|
||||||
void clear_timer(int timer_id);
|
void clear_timer(int timer_id);
|
||||||
void handle_readable();
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue