summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlouiz’ <louiz@louiz.org>2017-04-17 14:45:19 +0200
committerlouiz’ <louiz@louiz.org>2017-04-17 14:47:21 +0200
commit32384047537ed7c63cf3099b247777ed6035af49 (patch)
treee9a1277d0e567b794fbcc9b37663c6b90240714a
parentdc5ad49b4011bb637373c6088efaf219fed4a016 (diff)
downloadbiboumi-32384047537ed7c63cf3099b247777ed6035af49.tar.gz
biboumi-32384047537ed7c63cf3099b247777ed6035af49.tar.bz2
biboumi-32384047537ed7c63cf3099b247777ed6035af49.tar.xz
biboumi-32384047537ed7c63cf3099b247777ed6035af49.zip
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.
-rw-r--r--src/main.cpp5
-rw-r--r--src/utils/timed_events.hpp5
-rw-r--r--src/utils/timed_events_manager.cpp14
3 files changed, 22 insertions, 2 deletions
diff --git a/src/main.cpp b/src/main.cpp
index 2db89cc..1a9b065 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -179,19 +179,20 @@ int main(int ac, char** av)
{
if (xmpp_component->ever_auth)
{
+ static const std::string reconnect_name{"XMPP reconnection"};
if (xmpp_component->first_connection_try == true)
{ // immediately re-try to connect
xmpp_component->reset();
xmpp_component->start();
}
- else
+ else if (!TimedEventsManager::instance().find_event(reconnect_name))
{ // Re-connecting failed, we now try only each few seconds
auto reconnect_later = [xmpp_component]()
{
xmpp_component->reset();
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));
}
}
diff --git a/src/utils/timed_events.hpp b/src/utils/timed_events.hpp
index 393b38d..fa0fc50 100644
--- a/src/utils/timed_events.hpp
+++ b/src/utils/timed_events.hpp
@@ -125,6 +125,11 @@ public:
* Return the number of managed events.
*/
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:
std::vector<TimedEvent> events;
diff --git a/src/utils/timed_events_manager.cpp b/src/utils/timed_events_manager.cpp
index 67d61fe..75e6338 100644
--- a/src/utils/timed_events_manager.cpp
+++ b/src/utils/timed_events_manager.cpp
@@ -1,5 +1,7 @@
#include <utils/timed_events.hpp>
+#include <algorithm>
+
TimedEventsManager& TimedEventsManager::instance()
{
static TimedEventsManager inst;
@@ -67,7 +69,19 @@ std::size_t TimedEventsManager::cancel(const std::string& name)
return res;
}
+
+
std::size_t TimedEventsManager::size() const
{
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;
+}