[ndnSIM] util: Redirecting the scheduler of ndn-cxx to the scheduler of NS3
Change-Id: I82fdd94582a731c2238c6645e9ace21a2cacf2de
diff --git a/src/util/scheduler.cpp b/src/util/scheduler.cpp
index c2f5564..09a3f26 100644
--- a/src/util/scheduler.cpp
+++ b/src/util/scheduler.cpp
@@ -23,47 +23,28 @@
#include "scheduler.hpp"
+namespace ns3 {
+
+/// @cond include_hidden
+
+template<>
+struct EventMemberImplObjTraits<std::function<void()>> {
+ typedef std::function<void()> T;
+ static T&
+ GetReference(T& p)
+ {
+ return p;
+ }
+};
+
+/// @endcond
+
+} // namespace ns3
+
namespace ndn {
namespace util {
namespace scheduler {
-struct EventIdImpl
-{
- EventIdImpl(const Scheduler::EventQueue::iterator& event)
- : m_event(event)
- , m_isValid(true)
- {
- }
-
- void
- invalidate()
- {
- m_isValid = false;
- }
-
- bool
- isValid() const
- {
- return m_isValid;
- }
-
- operator const Scheduler::EventQueue::iterator&() const
- {
- return m_event;
- }
-
- void
- reset(const Scheduler::EventQueue::iterator& newIterator)
- {
- m_event = newIterator;
- m_isValid = true;
- }
-
-private:
- Scheduler::EventQueue::iterator m_event;
- bool m_isValid;
-};
-
Scheduler::EventInfo::EventInfo(const time::nanoseconds& after,
const Event& event)
: m_scheduledTime(time::steady_clock::now() + after)
@@ -92,111 +73,57 @@
Scheduler::Scheduler(boost::asio::io_service& ioService)
: m_scheduledEvent(m_events.end())
- , m_deadlineTimer(ioService)
- , m_isEventExecuting(false)
{
}
-EventId
-Scheduler::scheduleEvent(const time::nanoseconds& after,
- const Event& event)
+Scheduler::~Scheduler()
{
- EventQueue::iterator i = m_events.insert(EventInfo(after, event));
+ cancelAllEvents();
+}
- // On OSX 10.9, boost, and C++03 the following doesn't work without ndn::
- // because the argument-dependent lookup prefers STL to boost
- i->m_eventId = ndn::make_shared<EventIdImpl>(i);
-
- if (!m_isEventExecuting)
- {
- if (m_scheduledEvent == m_events.end() ||
- *i < *m_scheduledEvent)
- {
- m_deadlineTimer.expires_from_now(after);
- m_deadlineTimer.async_wait(bind(&Scheduler::onEvent, this, _1));
- m_scheduledEvent = i;
- }
+EventId
+Scheduler::scheduleEvent(const time::nanoseconds& after, const Event& event)
+{
+ EventId eventId = std::make_shared<ns3::EventId>();
+ weak_ptr<ns3::EventId> eventWeak = eventId;
+ std::function<void()> eventWithCleanup = [this, event, eventWeak] () {
+ event();
+ shared_ptr<ns3::EventId> eventId = eventWeak.lock();
+ if (eventId != nullptr) {
+ this->m_events.erase(eventId); // remove the event from the set after it is executed
}
+ };
- return i->m_eventId;
+ ns3::EventId id = ns3::Simulator::Schedule(ns3::NanoSeconds(after.count()),
+ &std::function<void()>::operator(), eventWithCleanup);
+ *eventId = std::move(id);
+ m_events.insert(eventId);
+
+ return eventId;
}
void
Scheduler::cancelEvent(const EventId& eventId)
{
- if (!static_cast<bool>(eventId) || !eventId->isValid())
- return; // event already fired or cancelled
-
- if (static_cast<EventQueue::iterator>(*eventId) != m_scheduledEvent) {
- m_events.erase(*eventId);
- eventId->invalidate();
- return;
+ if (eventId != nullptr) {
+ ns3::Simulator::Remove(*eventId);
+ const_cast<EventId&>(eventId).reset();
+ m_events.erase(eventId);
}
-
- m_deadlineTimer.cancel();
- m_events.erase(static_cast<EventQueue::iterator>(*eventId));
- eventId->invalidate();
-
- if (!m_isEventExecuting)
- {
- if (!m_events.empty())
- {
- m_deadlineTimer.expires_from_now(m_events.begin()->expiresFromNow());
- m_deadlineTimer.async_wait(bind(&Scheduler::onEvent, this, _1));
- m_scheduledEvent = m_events.begin();
- }
- else
- {
- m_scheduledEvent = m_events.end();
- }
- }
}
void
Scheduler::cancelAllEvents()
{
+ for (auto i = m_events.begin(); i != m_events.end(); i++) {
+ if ((*i) != nullptr) {
+ ns3::Simulator::Remove((**i));
+ const_cast<EventId&>(*i).reset();
+ }
+ }
m_events.clear();
- m_deadlineTimer.cancel();
}
-void
-Scheduler::onEvent(const boost::system::error_code& error)
-{
- if (error) // e.g., cancelled
- {
- return;
- }
-
- m_isEventExecuting = true;
-
- // process all expired events
- time::steady_clock::TimePoint now = time::steady_clock::now();
- while(!m_events.empty() && m_events.begin()->m_scheduledTime <= now)
- {
- EventQueue::iterator head = m_events.begin();
-
- Event event = head->m_event;
- head->m_eventId->invalidate();
- m_events.erase(head);
-
- event();
- }
-
- if (!m_events.empty())
- {
- m_deadlineTimer.expires_from_now(m_events.begin()->m_scheduledTime - now);
- m_deadlineTimer.async_wait(bind(&Scheduler::onEvent, this, _1));
- m_scheduledEvent = m_events.begin();
- }
- else
- {
- m_scheduledEvent = m_events.end();
- }
-
- m_isEventExecuting = false;
-}
-
-
} // namespace scheduler
} // namespace util
} // namespace ndn