timer: cancel all timers during reactor destruction

If a timer is not canceled it will try to cancel itself during
destruction which may happen after engine is already destroyed.
This commit is contained in:
Gleb Natapov
2014-12-24 17:46:27 +02:00
committed by Avi Kivity
parent 4d25571349
commit 466acedcb2
3 changed files with 26 additions and 1 deletions

View File

@@ -290,6 +290,11 @@ public:
}
}
// needed by timer_set
bool cancel() {
return false;
}
friend bool operator==(const item_type &a, const item_type &b) {
return a._key == b._key;
}

View File

@@ -645,6 +645,16 @@ public:
static boost::program_options::options_description get_options_description();
reactor();
reactor(const reactor&) = delete;
~reactor() {
auto eraser = [](auto& list) {
while (!list.empty()) {
auto timer = *list.begin();
timer.cancel();
}
};
eraser(_expired_timers);
eraser(_expired_lowres_timers);
}
void operator=(const reactor&) = delete;
void configure(boost::program_options::variables_map config);

View File

@@ -17,6 +17,7 @@
#include <chrono>
#include <limits>
#include <bitset>
#include <array>
#include <boost/intrusive/list.hpp>
#include "bitset-iter.hh"
@@ -48,7 +49,7 @@ private:
// The last bucket is reserved for active timers with timeout <= _last.
static constexpr int n_buckets = timestamp_bits + 1;
timer_list_t _buckets[n_buckets];
std::array<timer_list_t, n_buckets> _buckets;
timestamp_t _last;
timestamp_t _next;
@@ -92,6 +93,15 @@ public:
{
}
~timer_set() {
for (auto&& list : _buckets) {
while (!list.empty()) {
auto& timer = *list.begin();
timer.cancel();
}
}
}
/**
* Adds timer to the active set.
*