[ndnSIM] core: Partial emulation of boost::asio::io_service for NS-3

This commit assumes that ndn::Scheduler is redirected to ns3::Simulator
routines inside the ndn-cxx library.

Change-Id: Ib987f09f76a5d2103365312261fc5a2eba7024d2
diff --git a/core/global-io.cpp b/core/global-io.cpp
index f03d13c..29b1269 100644
--- a/core/global-io.cpp
+++ b/core/global-io.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2018,  Regents of the University of California,
+ * Copyright (c) 2014-2019,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -24,60 +24,45 @@
  */
 
 #include "global-io.hpp"
-#include <boost/thread/tss.hpp>
+#include "scheduler.hpp"
 
 namespace nfd {
 
-namespace scheduler {
-// defined in scheduler.cpp
+namespace detail {
+
 void
-resetGlobalScheduler();
-} // namespace scheduler
+SimulatorIo::post(const std::function<void()>& callback)
+{
+  scheduler::schedule(time::seconds(0), callback);
+}
 
-static boost::thread_specific_ptr<boost::asio::io_service> g_ioService;
-static boost::asio::io_service* g_mainIoService = nullptr;
-static boost::asio::io_service* g_ribIoService = nullptr;
+void
+SimulatorIo::dispatch(const std::function<void()>& callback)
+{
+  scheduler::schedule(time::seconds(0), callback);
+}
 
-boost::asio::io_service&
+} // namespace detail
+
+detail::SimulatorIo&
 getGlobalIoService()
 {
-  if (g_ioService.get() == nullptr) {
-    g_ioService.reset(new boost::asio::io_service());
-  }
-  return *g_ioService;
+  static detail::SimulatorIo io;
+  return io;
 }
 
-void
-resetGlobalIoService()
-{
-  scheduler::resetGlobalScheduler();
-  g_ioService.reset();
-}
-
-void
-setMainIoService(boost::asio::io_service* mainIo)
-{
-  g_mainIoService = mainIo;
-}
-
-void
-setRibIoService(boost::asio::io_service* ribIo)
-{
-  g_ribIoService = ribIo;
-}
-
-boost::asio::io_service&
+detail::SimulatorIo&
 getMainIoService()
 {
-  BOOST_ASSERT(g_mainIoService != nullptr);
-  return *g_mainIoService;
+  static detail::SimulatorIo io;
+  return io;
 }
 
-boost::asio::io_service&
+detail::SimulatorIo&
 getRibIoService()
 {
-  BOOST_ASSERT(g_ribIoService != nullptr);
-  return *g_ribIoService;
+  static detail::SimulatorIo io;
+  return io;
 }
 
 void
diff --git a/core/global-io.hpp b/core/global-io.hpp
index 0fb2fbe..e182dd7 100644
--- a/core/global-io.hpp
+++ b/core/global-io.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2018  Regents of the University of California,
+ * Copyright (c) 2014-2019  Regents of the University of California,
  *                          Arizona Board of Regents,
  *                          Colorado State University,
  *                          University Pierre & Marie Curie, Sorbonne University,
@@ -29,17 +29,28 @@
 
 namespace nfd {
 
-/** \return the global io_service instance
+namespace detail {
+
+/**
+ * @brief Simulator-based IO that implements a few interfaces from boost::asio::io_service
  */
-boost::asio::io_service&
+class SimulatorIo
+{
+public:
+  void
+  post(const std::function<void()>& callback);
+
+  void
+  dispatch(const std::function<void()>& callback);
+};
+
+} // namespace detail
+
+/** \return Simulator-based IO object
+ */
+detail::SimulatorIo&
 getGlobalIoService();
 
-void
-setMainIoService(boost::asio::io_service* mainIo);
-
-void
-setRibIoService(boost::asio::io_service* ribIo);
-
 /** \brief run a function on the main io_service instance
  */
 void
@@ -50,21 +61,12 @@
 void
 runOnRibIoService(const std::function<void()>& f);
 
-boost::asio::io_service&
+detail::SimulatorIo&
 getMainIoService();
 
-boost::asio::io_service&
+detail::SimulatorIo&
 getRibIoService();
 
-#ifdef WITH_TESTS
-/** \brief delete the global io_service instance
- *
- *  It will be recreated at the next invocation of getGlobalIoService.
- */
-void
-resetGlobalIoService();
-#endif
-
 } // namespace nfd
 
 #endif // NFD_CORE_GLOBAL_IO_HPP
diff --git a/core/scheduler.cpp b/core/scheduler.cpp
index 094c188..e4ef3b6 100644
--- a/core/scheduler.cpp
+++ b/core/scheduler.cpp
@@ -36,8 +36,9 @@
 Scheduler&
 getGlobalScheduler()
 {
+  static ndn::DummyIoService io;
   if (g_scheduler.get() == nullptr) {
-    g_scheduler.reset(new Scheduler(getGlobalIoService()));
+    g_scheduler.reset(new Scheduler(io));
   }
 
   return *g_scheduler;
diff --git a/core/scheduler.hpp b/core/scheduler.hpp
index 3ad448b..a8bb94a 100644
--- a/core/scheduler.hpp
+++ b/core/scheduler.hpp
@@ -51,6 +51,9 @@
   eventId.cancel();
 }
 
+void
+resetGlobalScheduler();
+
 } // namespace scheduler
 } // namespace nfd