~singpolyma/biboumi

5c9d2c23ba6a401bc9494a6023491bbf3ade8d34 — Florent Le Coz 10 years ago 5cca518
TimedEventsManager is now a singleton
4 files changed, 32 insertions(+), 30 deletions(-)

M src/main.cpp
M src/test.cpp
M src/utils/timed_events.hpp
M src/utils/timed_events_manager.cpp
M src/main.cpp => src/main.cpp +4 -11
@@ 18,13 18,6 @@ static volatile std::atomic<bool> reload(false);
// flag is set and all connections are closed, we can exit properly.
static bool exiting = false;

// The global (and only) TimedEventsManager.  It can be accessed by any
// class to add new TimedEvents, and it is used in the main loop to provide
// a timeout to the poller, this way the method execute_expired_events can
// be called on time, without having to do an active “poll” on it every n
// seconds.
TimedEventsManager timed_events;

/**
 * Provide an helpful message to help the user write a minimal working
 * configuration file.


@@ 43,7 36,7 @@ int config_help(const std::string& missing_option)
static void sigint_handler(int sig, siginfo_t*, void*)
{
  // In 2 seconds, repeat the same signal, to force the exit
  timed_events.add_event(TimedEvent(std::chrono::steady_clock::now() + 2s,
  TimedEventsManager::instance().add_event(TimedEvent(std::chrono::steady_clock::now() + 2s,
                                    [sig]() { raise(sig); }));
  stop.store(true);
}


@@ 101,10 94,10 @@ int main(int ac, char** av)

  xmpp_component->start();

  auto timeout = timed_events.get_timeout();
  auto timeout = TimedEventsManager::instance().get_timeout();
  while (p->poll(timeout) != -1)
  {
    timed_events.execute_expired_events();
    TimedEventsManager::instance().execute_expired_events();
    // Check for empty irc_clients (not connected, or with no joined
    // channel) and remove them
    xmpp_component->clean();


@@ 143,7 136,7 @@ int main(int ac, char** av)
      xmpp_component->close();
    if (exiting && p->size() == 1 && xmpp_component->is_document_open())
      xmpp_component->close_document();
    timeout = timed_events.get_timeout();
    timeout = TimedEventsManager::instance().get_timeout();
  }
  log_info("All connection cleanely closed, have a nice day.");
  return 0;

M src/test.cpp => src/test.cpp +17 -18
@@ 65,34 65,33 @@ int main()
   * Timed events
   */
  std::cout << color << "Testing timed events…" << reset << std::endl;
  TimedEventsManager te_manager;
  // No event.
  assert(te_manager.get_timeout() == utils::no_timeout);
  assert(te_manager.execute_expired_events() == 0);
  assert(TimedEventsManager::instance().get_timeout() == utils::no_timeout);
  assert(TimedEventsManager::instance().execute_expired_events() == 0);

  // Add a single event
  te_manager.add_event(TimedEvent(std::chrono::steady_clock::now() + 50ms, [](){ std::cout << "Timeout expired" << std::endl; }));
  TimedEventsManager::instance().add_event(TimedEvent(std::chrono::steady_clock::now() + 50ms, [](){ std::cout << "Timeout expired" << std::endl; }));
  // The event should not yet be expired
  assert(te_manager.get_timeout() > 0ms);
  assert(te_manager.execute_expired_events() == 0);
  std::chrono::milliseconds timoute = te_manager.get_timeout();
  assert(TimedEventsManager::instance().get_timeout() > 0ms);
  assert(TimedEventsManager::instance().execute_expired_events() == 0);
  std::chrono::milliseconds timoute = TimedEventsManager::instance().get_timeout();
  std::cout << "Sleeping for " << timoute.count() << "ms" << std::endl;
  std::this_thread::sleep_for(timoute);

  // Event is now expired
  assert(te_manager.execute_expired_events() == 1);
  assert(te_manager.get_timeout() == utils::no_timeout);
  assert(TimedEventsManager::instance().execute_expired_events() == 1);
  assert(TimedEventsManager::instance().get_timeout() == utils::no_timeout);

  // Test canceling events
  te_manager.add_event(TimedEvent(std::chrono::steady_clock::now() + 100ms, [](){ }, "un"));
  te_manager.add_event(TimedEvent(std::chrono::steady_clock::now() + 200ms, [](){ }, "deux"));
  te_manager.add_event(TimedEvent(std::chrono::steady_clock::now() + 300ms, [](){ }, "deux"));
  assert(te_manager.get_timeout() > 0ms);
  assert(te_manager.size() == 3);
  assert(te_manager.cancel("un") == 1);
  assert(te_manager.size() == 2);
  assert(te_manager.cancel("deux") == 2);
  assert(te_manager.get_timeout() == utils::no_timeout);
  TimedEventsManager::instance().add_event(TimedEvent(std::chrono::steady_clock::now() + 100ms, [](){ }, "un"));
  TimedEventsManager::instance().add_event(TimedEvent(std::chrono::steady_clock::now() + 200ms, [](){ }, "deux"));
  TimedEventsManager::instance().add_event(TimedEvent(std::chrono::steady_clock::now() + 300ms, [](){ }, "deux"));
  assert(TimedEventsManager::instance().get_timeout() > 0ms);
  assert(TimedEventsManager::instance().size() == 3);
  assert(TimedEventsManager::instance().cancel("un") == 1);
  assert(TimedEventsManager::instance().size() == 2);
  assert(TimedEventsManager::instance().cancel("deux") == 2);
  assert(TimedEventsManager::instance().get_timeout() == utils::no_timeout);

  /**
   * Encoding

M src/utils/timed_events.hpp => src/utils/timed_events.hpp +5 -1
@@ 83,9 83,12 @@ private:
class TimedEventsManager
{
public:
  explicit TimedEventsManager();
  ~TimedEventsManager();
  /**
   * Return the unique instance of this class
   */
  static TimedEventsManager& instance();
  /**
   * Add an event to the list of managed events. The list is sorted after
   * this call.
   */


@@ 117,6 120,7 @@ public:
  std::size_t size() const;

private:
  explicit TimedEventsManager();
  std::list<TimedEvent> events;
  TimedEventsManager(const TimedEventsManager&) = delete;
  TimedEventsManager(TimedEventsManager&&) = delete;

M src/utils/timed_events_manager.cpp => src/utils/timed_events_manager.cpp +6 -0
@@ 1,5 1,11 @@
#include <utils/timed_events.hpp>

TimedEventsManager& TimedEventsManager::instance()
{
  static TimedEventsManager inst;
  return inst;
}

TimedEventsManager::TimedEventsManager()
{
}