util: Introduce Scheduler::cancelAllEvents to cancel all previously scheduled events

Change-Id: I11e736bec855fe4122915486faec369237cf64a6
Refs: #1757
diff --git a/src/util/scheduler.cpp b/src/util/scheduler.cpp
index d51f83d..998728f 100644
--- a/src/util/scheduler.cpp
+++ b/src/util/scheduler.cpp
@@ -151,6 +151,13 @@
 }
 
 void
+Scheduler::cancelAllEvents()
+{
+  m_events.clear();
+  m_deadlineTimer.cancel();
+}
+
+void
 Scheduler::onEvent(const boost::system::error_code& error)
 {
   if (error) // e.g., cancelled
diff --git a/src/util/scheduler.hpp b/src/util/scheduler.hpp
index bf6ada5..4287556 100644
--- a/src/util/scheduler.hpp
+++ b/src/util/scheduler.hpp
@@ -58,6 +58,12 @@
   void
   cancelEvent(const EventId& eventId);
 
+  /**
+   * \brief Cancel all scheduled events
+   */
+  void
+  cancelAllEvents();
+
 private:
   void
   onEvent(const boost::system::error_code& code);
diff --git a/tests/unit-tests/util/test-scheduler.cpp b/tests/unit-tests/util/test-scheduler.cpp
index a046b93..04d4f99 100644
--- a/tests/unit-tests/util/test-scheduler.cpp
+++ b/tests/unit-tests/util/test-scheduler.cpp
@@ -217,6 +217,58 @@
 }
 
 
+struct CancelAllFixture
+{
+  CancelAllFixture()
+    : m_scheduler(m_io)
+    , m_count(0)
+  {
+  }
+
+  void
+  cancelAll()
+  {
+    m_scheduler.cancelAllEvents();
+  }
+
+  void
+  event()
+  {
+    ++m_count;
+
+    m_scheduler.scheduleEvent(time::seconds(1),
+                              bind(&CancelAllFixture::event, this));
+  }
+
+  void
+  abort()
+  {
+    m_io.stop();
+  }
+
+  boost::asio::io_service m_io;
+  Scheduler m_scheduler;
+  uint32_t m_count;
+};
+
+
+BOOST_FIXTURE_TEST_CASE(CancelAll, CancelAllFixture)
+{
+  m_scheduler.scheduleEvent(time::milliseconds(500),
+                            bind(&CancelAllFixture::cancelAll, this));
+
+  m_scheduler.scheduleEvent(time::seconds(1),
+                            bind(&CancelAllFixture::event, this));
+
+  m_scheduler.scheduleEvent(time::seconds(3),
+                            bind(&CancelAllFixture::abort, this));
+
+  BOOST_REQUIRE_NO_THROW(m_io.run());
+
+  BOOST_CHECK_EQUAL(m_count, 0);
+}
+
+
 BOOST_AUTO_TEST_SUITE_END()
 
 } // namespace ndn