~singpolyma/biboumi

32384047537ed7c63cf3099b247777ed6035af49 — louiz’ 5 years ago dc5ad49
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.
3 files changed, 22 insertions(+), 2 deletions(-)

M src/main.cpp
M src/utils/timed_events.hpp
M src/utils/timed_events_manager.cpp
M src/main.cpp => src/main.cpp +3 -2
@@ 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));
            }
        }

M src/utils/timed_events.hpp => src/utils/timed_events.hpp +5 -0
@@ 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;

M src/utils/timed_events_manager.cpp => src/utils/timed_events_manager.cpp +14 -0
@@ 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;
}