Avoid adding more that one “XMPP reconnection” timed event at the same time

Fix a semblance of infinite and busy loop, that could occur if biboumi’s
poller is woken up multiple times while the XMPP server is not reachable.
This commit is contained in:
louiz’
2017-04-17 14:47:21 +02:00
parent dc5ad49b40
commit 3238404753
3 changed files with 22 additions and 2 deletions
+3 -2
View File
@@ -179,19 +179,20 @@ int main(int ac, char** av)
{ {
if (xmpp_component->ever_auth) if (xmpp_component->ever_auth)
{ {
static const std::string reconnect_name{"XMPP reconnection"};
if (xmpp_component->first_connection_try == true) if (xmpp_component->first_connection_try == true)
{ // immediately re-try to connect { // immediately re-try to connect
xmpp_component->reset(); xmpp_component->reset();
xmpp_component->start(); xmpp_component->start();
} }
else else if (!TimedEventsManager::instance().find_event(reconnect_name))
{ // Re-connecting failed, we now try only each few seconds { // Re-connecting failed, we now try only each few seconds
auto reconnect_later = [xmpp_component]() auto reconnect_later = [xmpp_component]()
{ {
xmpp_component->reset(); xmpp_component->reset();
xmpp_component->start(); xmpp_component->start();
}; };
TimedEvent event(std::chrono::steady_clock::now() + 2s, reconnect_later, "XMPP reconnection"); TimedEvent event(std::chrono::steady_clock::now() + 2s, reconnect_later, reconnect_name);
TimedEventsManager::instance().add_event(std::move(event)); TimedEventsManager::instance().add_event(std::move(event));
} }
} }
+5
View File
@@ -125,6 +125,11 @@ public:
* Return the number of managed events. * Return the number of managed events.
*/ */
std::size_t size() const; std::size_t size() const;
/**
* Return a pointer to the first event with the given name. If none
* is found, returns nullptr.
*/
const TimedEvent* find_event(const std::string& name) const;
private: private:
std::vector<TimedEvent> events; std::vector<TimedEvent> events;
+14
View File
@@ -1,5 +1,7 @@
#include <utils/timed_events.hpp> #include <utils/timed_events.hpp>
#include <algorithm>
TimedEventsManager& TimedEventsManager::instance() TimedEventsManager& TimedEventsManager::instance()
{ {
static TimedEventsManager inst; static TimedEventsManager inst;
@@ -67,7 +69,19 @@ std::size_t TimedEventsManager::cancel(const std::string& name)
return res; return res;
} }
std::size_t TimedEventsManager::size() const std::size_t TimedEventsManager::size() const
{ {
return this->events.size(); return this->events.size();
} }
const TimedEvent* TimedEventsManager::find_event(const std::string& name) const
{
const auto it = std::find_if(this->events.begin(), this->events.end(), [&name](const TimedEvent& o) {
return o.get_name() == name;
});
if (it == this->events.end())
return nullptr;
return &*it;
}