add support to cancel Now and Destroy events.
authorMathieu Lacage <mathieu.lacage@sophia.inria.fr>
Mon, 23 Jul 2007 14:52:51 +0200
changeset 963 3a7a66d1942c
parent 962 473a781ec774
child 964 e49de7414508
add support to cancel Now and Destroy events.
src/simulator/scheduler-heap.cc
src/simulator/scheduler-heap.h
src/simulator/scheduler-list.cc
src/simulator/scheduler-list.h
src/simulator/scheduler-map.cc
src/simulator/scheduler-map.h
src/simulator/scheduler.cc
src/simulator/scheduler.h
src/simulator/simulator.cc
src/simulator/simulator.h
--- a/src/simulator/scheduler-heap.cc	Mon Jul 23 14:51:57 2007 +0200
+++ b/src/simulator/scheduler-heap.cc	Mon Jul 23 14:52:51 2007 +0200
@@ -222,23 +222,22 @@
 }
 
 
-EventId
-SchedulerHeap::RealInsert (EventImpl *event, Scheduler::EventKey key)
+void
+SchedulerHeap::RealInsert (EventId id)
 {
+  EventImpl *event = id.GetEventImpl ();
+  Scheduler::EventKey key;
+  key.m_ts = id.GetTs ();
+  key.m_uid = id.GetUid ();
   m_heap.push_back (std::make_pair (event, key));
   BottomUp ();
-  return EventId (event, key.m_ts, key.m_uid);
 }
 
-EventImpl *
+EventId
 SchedulerHeap::RealPeekNext (void) const
 {
-  return m_heap[Root ()].first;
-}
-Scheduler::EventKey
-SchedulerHeap::RealPeekNextKey (void) const
-{
-  return m_heap[Root ()].second;
+  std::pair<EventImpl *,Scheduler::EventKey> next = m_heap[Root ()];
+  return EventId (next.first, next.second.m_ts, next.second.m_uid);
 }
 void     
 SchedulerHeap::RealRemoveNext (void)
@@ -249,31 +248,25 @@
 }
 
 
-EventImpl *
-SchedulerHeap::RealRemove (EventId id, Scheduler::EventKey *key)
+bool
+SchedulerHeap::RealRemove (EventId id)
 {
-  key->m_ts = id.GetTs ();
-  key->m_uid = id.GetUid ();
+  uint32_t uid = id.GetUid ();
   for (uint32_t i = 1; i < m_heap.size (); i++)
     {
-      if (key->m_uid == m_heap[i].second.m_uid)
+      if (uid == m_heap[i].second.m_uid)
         {
-          EventImpl *retval = m_heap[i].first;
+          NS_ASSERT (m_heap[i].first == id.GetEventImpl ());
           Exch (i, Last ());
           m_heap.pop_back ();
           TopDown (i);
-          return retval;
+          return true;
         }
     }
   NS_ASSERT (false);
   // quiet compiler
-  return 0;
+  return false;
 }
 
-bool 
-SchedulerHeap::RealIsValid (EventId id)
-{
-  return true;
-}
 }; // namespace ns3
 
--- a/src/simulator/scheduler-heap.h	Mon Jul 23 14:51:57 2007 +0200
+++ b/src/simulator/scheduler-heap.h	Mon Jul 23 14:52:51 2007 +0200
@@ -36,13 +36,11 @@
   virtual ~SchedulerHeap ();
 
 private:
-  virtual EventId RealInsert (EventImpl *event, Scheduler::EventKey key);
+  virtual void RealInsert (EventId id);
   virtual bool RealIsEmpty (void) const;
-  virtual EventImpl *RealPeekNext (void) const;
-  virtual Scheduler::EventKey RealPeekNextKey (void) const;
+  virtual EventId RealPeekNext (void) const;
   virtual void RealRemoveNext (void);
-  virtual EventImpl *RealRemove (EventId ev, Scheduler::EventKey *key);
-  virtual bool RealIsValid (EventId id);
+  virtual bool RealRemove (EventId ev);
 
   typedef std::vector<std::pair<EventImpl *, Scheduler::EventKey> > BinaryHeap;
 
--- a/src/simulator/scheduler-list.cc	Mon Jul 23 14:51:57 2007 +0200
+++ b/src/simulator/scheduler-list.cc	Mon Jul 23 14:52:51 2007 +0200
@@ -66,34 +66,33 @@
     }
 }
 
-EventId
-SchedulerList::RealInsert (EventImpl *event, Scheduler::EventKey key)
+void
+SchedulerList::RealInsert (EventId id)
 {
+  Scheduler::EventKey key;
+  EventImpl *event = id.GetEventImpl ();
+  key.m_ts = id.GetTs ();
+  key.m_uid = id.GetUid ();
   for (EventsI i = m_events.begin (); i != m_events.end (); i++) 
     {
       if (IsLower (&key, &i->second))
         {
           m_events.insert (i, std::make_pair (event, key));
-          return EventId (event, key.m_ts, key.m_uid);
+          return;
         }
     }
   m_events.push_back (std::make_pair (event, key));
-  return EventId (event, key.m_ts, key.m_uid);
 }
 bool 
 SchedulerList::RealIsEmpty (void) const
 {
   return m_events.empty ();
 }
-EventImpl *
+EventId
 SchedulerList::RealPeekNext (void) const
 {
-  return m_events.front ().first;
-}
-Scheduler::EventKey
-SchedulerList::RealPeekNextKey (void) const
-{
-  return m_events.front ().second;
+  std::pair<EventImpl *, EventKey> next = m_events.front ();
+  return EventId (next.first, next.second.m_ts, next.second.m_uid);
 }
 
 void
@@ -102,29 +101,20 @@
   m_events.pop_front ();
 }
 
-EventImpl *
-SchedulerList::RealRemove (EventId id, Scheduler::EventKey *key)
+bool
+SchedulerList::RealRemove (EventId id)
 {
   for (EventsI i = m_events.begin (); i != m_events.end (); i++) 
     {
       if (i->second.m_uid == id.GetUid ())
         {
-          EventImpl *retval = i->first;
-          NS_ASSERT (id.GetEventImpl () == retval);
-          key->m_ts = id.GetTs ();
-          key->m_uid = id.GetUid ();
+          NS_ASSERT (id.GetEventImpl () == i->first);
           m_events.erase (i);
-          return retval;
+          return true;
         }
     }
   NS_ASSERT (false);
-  return 0;
-}
-
-bool 
-SchedulerList::RealIsValid (EventId id)
-{
-  return true;
+  return false;
 }
 
 }; // namespace ns3
--- a/src/simulator/scheduler-list.h	Mon Jul 23 14:51:57 2007 +0200
+++ b/src/simulator/scheduler-list.h	Mon Jul 23 14:52:51 2007 +0200
@@ -38,13 +38,11 @@
   virtual ~SchedulerList ();
 
  private:
-  virtual EventId RealInsert (EventImpl *event, EventKey key);
+  virtual void RealInsert (EventId id);
   virtual bool RealIsEmpty (void) const;
-  virtual EventImpl *RealPeekNext (void) const;
-  virtual Scheduler::EventKey RealPeekNextKey (void) const;
+  virtual EventId RealPeekNext (void) const;
   virtual void RealRemoveNext (void);
-  virtual EventImpl *RealRemove (EventId ev, Scheduler::EventKey *key);
-  virtual bool RealIsValid (EventId id);
+  virtual bool RealRemove (EventId ev);
 
   inline bool IsLower (Scheduler::EventKey const*a, Scheduler::EventKey const*b) const;
 
--- a/src/simulator/scheduler-map.cc	Mon Jul 23 14:51:57 2007 +0200
+++ b/src/simulator/scheduler-map.cc	Mon Jul 23 14:52:51 2007 +0200
@@ -87,13 +87,16 @@
 
 
 
-EventId
-SchedulerMap::RealInsert (EventImpl *event, Scheduler::EventKey key)
+void
+SchedulerMap::RealInsert (EventId id)
 {
+  EventImpl *event = id.GetEventImpl ();
+  Scheduler::EventKey key;
+  key.m_ts = id.GetTs ();
+  key.m_uid = id.GetUid ();
   std::pair<EventMapI,bool> result;
   result = m_list.insert (std::make_pair (key, event));
   NS_ASSERT (result.second);
-  return EventId (event, key.m_ts, key.m_uid);
 }
 
 bool
@@ -102,19 +105,13 @@
   return m_list.empty ();
 }
 
-EventImpl *
+EventId
 SchedulerMap::RealPeekNext (void) const
 {
   EventMapCI i = m_list.begin ();
   NS_ASSERT (i != m_list.end ());
-  return (*i).second;
-}
-Scheduler::EventKey
-SchedulerMap::RealPeekNextKey (void) const
-{
-  EventMapCI i = m_list.begin ();
-  NS_ASSERT (i != m_list.end ());
-  return (*i).first;
+  
+  return EventId (i->second, i->first.m_ts, i->first.m_uid);
 }
 void
 SchedulerMap::RealRemoveNext (void)
@@ -122,22 +119,16 @@
   m_list.erase (m_list.begin ());
 }
 
-EventImpl *
-SchedulerMap::RealRemove (EventId id, Scheduler::EventKey *key)
+bool
+SchedulerMap::RealRemove (EventId id)
 {
-  key->m_ts = id.GetTs ();
-  key->m_uid = id.GetUid ();
-  EventMapI i = m_list.find (*key);
-  EventImpl *retval = i->second;
+  Scheduler::EventKey key;
+  key.m_ts = id.GetTs ();
+  key.m_uid = id.GetUid ();
+  EventMapI i = m_list.find (key);
+  NS_ASSERT (i->second == id.GetEventImpl ());
   m_list.erase (i);
-  return retval;
-}
-
-bool
-SchedulerMap::RealIsValid (EventId id)
-{
   return true;
 }
 
-
 }; // namespace ns3
--- a/src/simulator/scheduler-map.h	Mon Jul 23 14:51:57 2007 +0200
+++ b/src/simulator/scheduler-map.h	Mon Jul 23 14:52:51 2007 +0200
@@ -37,13 +37,11 @@
   virtual ~SchedulerMap ();
 
 private:
-  virtual EventId RealInsert (EventImpl *event, Scheduler::EventKey key);
+  virtual void RealInsert (EventId id);
   virtual bool RealIsEmpty (void) const;
-  virtual EventImpl *RealPeekNext (void) const;
-  virtual Scheduler::EventKey RealPeekNextKey (void) const;
+  virtual EventId RealPeekNext (void) const;
   virtual void RealRemoveNext (void);
-  virtual EventImpl *RealRemove (EventId ev, Scheduler::EventKey *key);
-  virtual bool RealIsValid (EventId id);
+  virtual bool RealRemove (EventId ev);
 
   class EventKeyCompare {
   public:
@@ -56,7 +54,6 @@
 
 
   EventMap m_list;
-  uint32_t m_uid;
 };
 
 }; // namespace ns3
--- a/src/simulator/scheduler.cc	Mon Jul 23 14:51:57 2007 +0200
+++ b/src/simulator/scheduler.cc	Mon Jul 23 14:52:51 2007 +0200
@@ -27,39 +27,33 @@
 Scheduler::~Scheduler () 
 {}
 
-EventId 
-Scheduler::Insert (EventImpl *event, struct EventKey key)
+void
+Scheduler::Insert (EventId id)
 {
-  return RealInsert (event, key);
+  return RealInsert (id);
 }
 bool 
 Scheduler::IsEmpty (void) const
 {
   return RealIsEmpty ();
 }
-EventImpl *
+EventId
 Scheduler::PeekNext (void) const
 {
   NS_ASSERT (!RealIsEmpty ());
   return RealPeekNext ();
 }
-Scheduler::EventKey 
-Scheduler::PeekNextKey (void) const 
-{
-  NS_ASSERT (!RealIsEmpty ());
-  return RealPeekNextKey ();
-}
 void 
 Scheduler::RemoveNext (void)
 {
   NS_ASSERT (!RealIsEmpty ());
   return RealRemoveNext ();
 }
-EventImpl *
-Scheduler::Remove (EventId id, EventKey *key)
+bool
+Scheduler::Remove (EventId id)
 {
   NS_ASSERT (!RealIsEmpty ());
-  return RealRemove (id, key);
+  return RealRemove (id);
 }
 
 }; // namespace ns3
--- a/src/simulator/scheduler.h	Mon Jul 23 14:51:57 2007 +0200
+++ b/src/simulator/scheduler.h	Mon Jul 23 14:52:51 2007 +0200
@@ -42,7 +42,6 @@
  *   - ns3::Scheduler::realPeekNextKey
  *   - ns3::Scheduler::realRemoveNext
  *   - ns3::Scheduler::realRemove
- *   - ns3::Scheduler::realIsValid
  *
  * If you need to provide a new event list scheduler without
  * editing the main simulator class, you need to also implement
@@ -61,12 +60,11 @@
 
   virtual ~Scheduler () = 0;
 
-  EventId Insert (EventImpl *event, EventKey key);
+  void Insert (EventId id);
   bool IsEmpty (void) const;
-  EventImpl *PeekNext (void) const;
-  Scheduler::EventKey PeekNextKey (void) const ;
+  EventId PeekNext (void) const;
   void RemoveNext (void);
-  EventImpl *Remove (EventId id, EventKey *key);
+  bool Remove (EventId);
 
 private:
   /**
@@ -76,7 +74,7 @@
    *
    * This method takes ownership of the event pointer.
    */
-  virtual EventId RealInsert (EventImpl *event, EventKey key) = 0;
+  virtual void RealInsert (EventId id) = 0;
   /**
    * \returns true if the event list is empty and false otherwise.
    */
@@ -87,13 +85,7 @@
    *
    * This method cannot be invoked if the list is empty.
    */
-  virtual EventImpl *RealPeekNext (void) const = 0;
-  /**
-   * \returns the timecode associated with the next earliest event.
-   *
-   * This method cannot be invoked if the list is empty.
-   */
-  virtual Scheduler::EventKey RealPeekNextKey (void) const = 0;
+  virtual EventId RealPeekNext (void) const = 0;
   /**
    * This method cannot be invoked if the list is empty.
    * Remove the next earliest event from the event list.
@@ -107,7 +99,7 @@
    *
    * This methods cannot be invoked if the list is empty.
    */
-  virtual EventImpl *RealRemove (EventId id, EventKey *key) = 0;
+  virtual bool RealRemove (EventId id) = 0;
 };
 
 }; // namespace ns3
--- a/src/simulator/simulator.cc	Mon Jul 23 14:51:57 2007 +0200
+++ b/src/simulator/simulator.cc	Mon Jul 23 14:52:51 2007 +0200
@@ -62,8 +62,8 @@
   void Stop (void);
   void StopAt (Time const &time);
   EventId Schedule (Time const &time, EventImpl *event);
-  void ScheduleNow (EventImpl *event);
-  void ScheduleDestroy (EventImpl *event);
+  EventId ScheduleNow (EventImpl *event);
+  EventId ScheduleDestroy (EventImpl *event);
   void Remove (EventId ev);
   void Cancel (EventId &ev);
   bool IsExpired (EventId ev);
@@ -74,8 +74,8 @@
   void ProcessOneEvent (void);
   uint64_t NextTs (void) const;
 
-  typedef std::list<std::pair<EventImpl *,uint32_t> > Events;
-  Events m_destroy;
+  typedef std::list<EventId> DestroyEvents;
+  DestroyEvents m_destroyEvents;
   uint64_t m_stopAt;
   bool m_stop;
   Scheduler *m_events;
@@ -98,8 +98,11 @@
   m_stop = false;
   m_stopAt = 0;
   m_events = events;
-  // uids are allocated from 1.
-  m_uid = 1; 
+  // uids are allocated from 4.
+  // uid 0 is "invalid" events
+  // uid 1 is "now" events
+  // uid 2 is "destroy" events
+  m_uid = 4; 
   // before ::Run is entered, the m_currentUid will be zero
   m_currentUid = 0;
   m_logEnable = false;
@@ -109,13 +112,16 @@
 
 SimulatorPrivate::~SimulatorPrivate ()
 {
-  while (!m_destroy.empty ()) 
+  while (!m_destroyEvents.empty ()) 
     {
-      EventImpl *ev = m_destroy.front ().first;
-      m_destroy.pop_front ();
+      EventImpl *ev = m_destroyEvents.front ().GetEventImpl ();
+      m_destroyEvents.pop_front ();
       TRACE ("handle destroy " << ev);
-      ev->Invoke ();
-      delete ev;
+      if (!ev->IsCancelled ())
+        {
+          ev->Invoke ();
+          delete ev;
+        }
     }
   delete m_events;
   m_events = (Scheduler *)0xdeadbeaf;
@@ -132,22 +138,22 @@
 void
 SimulatorPrivate::ProcessOneEvent (void)
 {
-  EventImpl *nextEv = m_events->PeekNext ();
-  Scheduler::EventKey nextKey = m_events->PeekNextKey ();
+  EventId next = m_events->PeekNext ();
   m_events->RemoveNext ();
 
-  NS_ASSERT (nextKey.m_ts >= m_currentTs);
+  NS_ASSERT (next.GetTs () >= m_currentTs);
   --m_unscheduledEvents;
 
   TRACE ("handle " << nextEv);
-  m_currentTs = nextKey.m_ts;
-  m_currentUid = nextKey.m_uid;
+  m_currentTs = next.GetTs ();
+  m_currentUid = next.GetUid ();
   if (m_logEnable) 
     {
-      m_log << "e "<<nextKey.m_uid << " " << nextKey.m_ts << std::endl;
+      m_log << "e "<<next.GetUid () << " " << next.GetTs () << std::endl;
     }
-  nextEv->Invoke ();
-  delete nextEv;
+  EventImpl *event = next.GetEventImpl ();
+  event->Invoke ();
+  delete event;
 }
 
 bool 
@@ -159,8 +165,8 @@
 SimulatorPrivate::NextTs (void) const
 {
   NS_ASSERT (!m_events->IsEmpty ());
-  Scheduler::EventKey nextKey = m_events->PeekNextKey ();
-  return nextKey.m_ts;
+  EventId id = m_events->PeekNext ();
+  return id.GetTs ();
 }
 Time
 SimulatorPrivate::Next (void) const
@@ -203,7 +209,7 @@
   NS_ASSERT (time.IsPositive ());
   NS_ASSERT (time >= TimeStep (m_currentTs));
   uint64_t ts = (uint64_t) time.GetTimeStep ();
-  Scheduler::EventKey key = {ts, m_uid};
+  EventId id (event, ts, m_uid);
   if (m_logEnable) 
     {
       m_log << "i "<<m_currentUid<<" "<<m_currentTs<<" "
@@ -211,32 +217,35 @@
     }
   m_uid++;
   ++m_unscheduledEvents;
-  return m_events->Insert (event, key);
+  m_events->Insert (id);
+  return id;
 }
-void 
+EventId
 SimulatorPrivate::ScheduleNow (EventImpl *event)
 {
-  uint64_t ts = m_currentTs;
-  Scheduler::EventKey key = {ts, m_uid};
+  EventId id (event, m_currentTs, m_uid);
   if (m_logEnable) 
     {
       m_log << "i "<<m_currentUid<<" "<<m_currentTs<<" "
-            <<m_uid<<" "<<ts << std::endl;
+            <<m_uid<<" "<<m_currentTs << std::endl;
     }
   m_uid++;
   ++m_unscheduledEvents;
-  m_events->Insert (event, key);
+  m_events->Insert (id);
+  return id;
 }
-void 
+EventId
 SimulatorPrivate::ScheduleDestroy (EventImpl *event)
 {
-  m_destroy.push_back (std::make_pair (event, m_uid));  
+  EventId id (event, m_currentTs, 2);
+  m_destroyEvents.push_back (id);
   if (m_logEnable) 
   {
     m_log << "id " << m_currentUid << " " << Now ().GetTimeStep () << " "
           << m_uid << std::endl;
   }
   m_uid++;
+  return id;
 }
 
 Time
@@ -248,13 +257,30 @@
 void
 SimulatorPrivate::Remove (EventId ev)
 {
-  Scheduler::EventKey key;
-  EventImpl *impl = m_events->Remove (ev, &key);
-  delete impl;
+  if (ev.GetUid () == 2)
+    {
+      // destroy events.
+      for (DestroyEvents::iterator i = m_destroyEvents.begin (); i != m_destroyEvents.end (); i++)
+        {
+          if (*i == ev)
+            {
+              m_destroyEvents.erase (i);
+              break;
+            }
+         }
+      return;
+    }
+  if (IsExpired (ev))
+    {
+      return;
+    }
+  m_events->Remove (ev);
+  delete ev.GetEventImpl ();
+
   if (m_logEnable) 
     {
       m_log << "r " << m_currentUid << " " << m_currentTs << " "
-            << key.m_uid << " " << key.m_ts << std::endl;
+            << ev.GetUid () << " " << ev.GetTs () << std::endl;
     }
   --m_unscheduledEvents;
 }
@@ -399,27 +425,27 @@
 {
   return GetPriv ()->Schedule (Now () + time, ev);
 }
-void
+EventId
 Simulator::ScheduleNow (EventImpl *ev)
 {
-  GetPriv ()->ScheduleNow (ev);
+  return GetPriv ()->ScheduleNow (ev);
 }
-void
+EventId
 Simulator::ScheduleDestroy (EventImpl *ev)
 {
-  GetPriv ()->ScheduleDestroy (ev);
+  return GetPriv ()->ScheduleDestroy (ev);
 }  
 EventId
 Simulator::Schedule (Time const &time, void (*f) (void))
 {
   return Schedule (time, MakeEvent (f));
 }
-void
+EventId
 Simulator::ScheduleNow (void (*f) (void))
 {
   return ScheduleNow (MakeEvent (f));
 }
-void
+EventId
 Simulator::ScheduleDestroy (void (*f) (void))
 {
   return ScheduleDestroy (MakeEvent (f));
@@ -820,6 +846,9 @@
   Simulator::ScheduleDestroy (&SimulatorTests::baz5, this, 0, 0, 0, 0, 0);
 #endif
 
+  EventId nowId = Simulator::ScheduleNow (&foo0);
+  EventId destroyId = Simulator::ScheduleDestroy (&foo0);
+
   Simulator::Run ();
   Simulator::Destroy ();
 
--- a/src/simulator/simulator.h	Mon Jul 23 14:51:57 2007 +0200
+++ b/src/simulator/simulator.h	Mon Jul 23 14:52:51 2007 +0200
@@ -296,7 +296,7 @@
    * @param obj the object on which to invoke the member method
    */
   template <typename T, typename OBJ>
-  static void ScheduleNow (void (T::*mem_ptr) (void), OBJ obj);
+  static EventId ScheduleNow (void (T::*mem_ptr) (void), OBJ obj);
   /**
    * @param mem_ptr member method pointer to invoke
    * @param obj the object on which to invoke the member method
@@ -305,7 +305,7 @@
   template <typename T, typename OBJ, 
             typename U1,  
             typename T1>
-  static void ScheduleNow (void (T::*mem_ptr) (U1), OBJ obj, T1 a1);
+  static EventId ScheduleNow (void (T::*mem_ptr) (U1), OBJ obj, T1 a1);
   /**
    * @param mem_ptr member method pointer to invoke
    * @param obj the object on which to invoke the member method
@@ -315,7 +315,7 @@
   template <typename T, typename OBJ, 
             typename U1, typename U2,
             typename T1, typename T2>
-  static void ScheduleNow (void (T::*mem_ptr) (U1,U2), OBJ obj, T1 a1, T2 a2);
+  static EventId ScheduleNow (void (T::*mem_ptr) (U1,U2), OBJ obj, T1 a1, T2 a2);
   /**
    * @param mem_ptr member method pointer to invoke
    * @param obj the object on which to invoke the member method
@@ -326,7 +326,7 @@
   template <typename T, typename OBJ, 
             typename U1, typename U2, typename U3,
             typename T1, typename T2, typename T3>
-  static void ScheduleNow (void (T::*mem_ptr) (U1,U2,U3), OBJ obj, T1 a1, T2 a2, T3 a3);
+  static EventId ScheduleNow (void (T::*mem_ptr) (U1,U2,U3), OBJ obj, T1 a1, T2 a2, T3 a3);
   /**
    * @param mem_ptr member method pointer to invoke
    * @param obj the object on which to invoke the member method
@@ -338,7 +338,7 @@
   template <typename T, typename OBJ, 
             typename U1, typename U2, typename U3, typename U4,
             typename T1, typename T2, typename T3, typename T4>
-  static void ScheduleNow (void (T::*mem_ptr) (U1,U2,U3,U4), OBJ obj, 
+  static EventId ScheduleNow (void (T::*mem_ptr) (U1,U2,U3,U4), OBJ obj, 
                            T1 a1, T2 a2, T3 a3, T4 a4);
   /**
    * @param mem_ptr member method pointer to invoke
@@ -352,19 +352,19 @@
   template <typename T, typename OBJ, 
             typename U1, typename U2, typename U3, typename U4, typename U5,
             typename T1, typename T2, typename T3, typename T4, typename T5>
-  static void ScheduleNow (void (T::*mem_ptr) (U1,U2,U3,U4,U5), OBJ obj, 
+  static EventId ScheduleNow (void (T::*mem_ptr) (U1,U2,U3,U4,U5), OBJ obj, 
                            T1 a1, T2 a2, T3 a3, T4 a4, T5 a5);
   /**
    * @param f the function to invoke
    */
-  static void ScheduleNow (void (*f) (void));
+  static EventId ScheduleNow (void (*f) (void));
   /**
    * @param f the function to invoke
    * @param a1 the first argument to pass to the function to invoke
    */
   template <typename U1,
             typename T1>
-  static void ScheduleNow (void (*f) (U1), T1 a1);
+  static EventId ScheduleNow (void (*f) (U1), T1 a1);
   /**
    * @param f the function to invoke
    * @param a1 the first argument to pass to the function to invoke
@@ -372,7 +372,7 @@
    */
   template <typename U1, typename U2,
             typename T1, typename T2>
-  static void ScheduleNow (void (*f) (U1,U2), T1 a1, T2 a2);
+  static EventId ScheduleNow (void (*f) (U1,U2), T1 a1, T2 a2);
   /**
    * @param f the function to invoke
    * @param a1 the first argument to pass to the function to invoke
@@ -381,7 +381,7 @@
    */
   template <typename U1, typename U2, typename U3,
             typename T1, typename T2, typename T3>
-  static void ScheduleNow (void (*f) (U1,U2,U3), T1 a1, T2 a2, T3 a3);
+  static EventId ScheduleNow (void (*f) (U1,U2,U3), T1 a1, T2 a2, T3 a3);
   /**
    * @param f the function to invoke
    * @param a1 the first argument to pass to the function to invoke
@@ -391,7 +391,7 @@
    */
   template <typename U1, typename U2, typename U3, typename U4,
             typename T1, typename T2, typename T3, typename T4>
-  static void ScheduleNow (void (*f) (U1,U2,U3,U4), T1 a1, T2 a2, T3 a3, T4 a4);
+  static EventId ScheduleNow (void (*f) (U1,U2,U3,U4), T1 a1, T2 a2, T3 a3, T4 a4);
   /**
    * @param f the function to invoke
    * @param a1 the first argument to pass to the function to invoke
@@ -402,7 +402,7 @@
    */
   template <typename U1, typename U2, typename U3, typename U4, typename U5,
             typename T1, typename T2, typename T3, typename T4, typename T5>
-  static void ScheduleNow (void (*f) (U1,U2,U3,U4,U5), T1 a1, T2 a2, T3 a3, T4 a4, T5 a5);
+  static EventId ScheduleNow (void (*f) (U1,U2,U3,U4,U5), T1 a1, T2 a2, T3 a3, T4 a4, T5 a5);
 
 
   /**
@@ -415,7 +415,7 @@
    * @param obj the object on which to invoke the member method
    */
   template <typename T, typename OBJ>
-  static void ScheduleDestroy (void (T::*mem_ptr) (void), OBJ obj);
+  static EventId ScheduleDestroy (void (T::*mem_ptr) (void), OBJ obj);
   /**
    * @param mem_ptr member method pointer to invoke
    * @param obj the object on which to invoke the member method
@@ -424,7 +424,7 @@
   template <typename T, typename OBJ, 
             typename U1,
             typename T1>
-  static void ScheduleDestroy (void (T::*mem_ptr) (U1), OBJ obj, T1 a1);
+  static EventId ScheduleDestroy (void (T::*mem_ptr) (U1), OBJ obj, T1 a1);
   /**
    * @param mem_ptr member method pointer to invoke
    * @param obj the object on which to invoke the member method
@@ -434,7 +434,7 @@
   template <typename T, typename OBJ,
             typename U1, typename U2,
             typename T1, typename T2>
-  static void ScheduleDestroy (void (T::*mem_ptr) (U1,U2), OBJ obj, T1 a1, T2 a2);
+  static EventId ScheduleDestroy (void (T::*mem_ptr) (U1,U2), OBJ obj, T1 a1, T2 a2);
   /**
    * @param mem_ptr member method pointer to invoke
    * @param obj the object on which to invoke the member method
@@ -445,7 +445,7 @@
   template <typename T, typename OBJ, 
             typename U1, typename U2, typename U3,
             typename T1, typename T2, typename T3>
-  static void ScheduleDestroy (void (T::*mem_ptr) (U1,U2,U3), OBJ obj, T1 a1, T2 a2, T3 a3);
+  static EventId ScheduleDestroy (void (T::*mem_ptr) (U1,U2,U3), OBJ obj, T1 a1, T2 a2, T3 a3);
   /**
    * @param mem_ptr member method pointer to invoke
    * @param obj the object on which to invoke the member method
@@ -457,7 +457,7 @@
   template <typename T, typename OBJ, 
             typename U1, typename U2, typename U3, typename U4,
             typename T1, typename T2, typename T3, typename T4>
-  static void ScheduleDestroy (void (T::*mem_ptr) (U1,U2,U3,U4), OBJ obj, 
+  static EventId ScheduleDestroy (void (T::*mem_ptr) (U1,U2,U3,U4), OBJ obj, 
                                T1 a1, T2 a2, T3 a3, T4 a4);
   /**
    * @param mem_ptr member method pointer to invoke
@@ -471,19 +471,19 @@
   template <typename T, typename OBJ, 
             typename U1, typename U2, typename U3, typename U4, typename U5,
             typename T1, typename T2, typename T3, typename T4, typename T5>
-  static void ScheduleDestroy (void (T::*mem_ptr) (U1,U2,U3,U4,U5), OBJ obj, 
+  static EventId ScheduleDestroy (void (T::*mem_ptr) (U1,U2,U3,U4,U5), OBJ obj, 
                                T1 a1, T2 a2, T3 a3, T4 a4, T5 a5);
   /**
    * @param f the function to invoke
    */
-  static void ScheduleDestroy (void (*f) (void));
+  static EventId ScheduleDestroy (void (*f) (void));
   /**
    * @param f the function to invoke
    * @param a1 the first argument to pass to the function to invoke
    */
   template <typename U1,
             typename T1>
-  static void ScheduleDestroy (void (*f) (U1), T1 a1);
+  static EventId ScheduleDestroy (void (*f) (U1), T1 a1);
   /**
    * @param f the function to invoke
    * @param a1 the first argument to pass to the function to invoke
@@ -491,7 +491,7 @@
    */
   template <typename U1, typename U2,
             typename T1, typename T2>
-  static void ScheduleDestroy (void (*f) (U1,U2), T1 a1, T2 a2);
+  static EventId ScheduleDestroy (void (*f) (U1,U2), T1 a1, T2 a2);
   /**
    * @param f the function to invoke
    * @param a1 the first argument to pass to the function to invoke
@@ -500,7 +500,7 @@
    */
   template <typename U1, typename U2, typename U3,
             typename T1, typename T2, typename T3>
-  static void ScheduleDestroy (void (*f) (U1,U2,U3), T1 a1, T2 a2, T3 a3);
+  static EventId ScheduleDestroy (void (*f) (U1,U2,U3), T1 a1, T2 a2, T3 a3);
   /**
    * @param f the function to invoke
    * @param a1 the first argument to pass to the function to invoke
@@ -510,7 +510,7 @@
    */
   template <typename U1, typename U2, typename U3, typename U4,
             typename T1, typename T2, typename T3, typename T4>
-  static void ScheduleDestroy (void (*f) (U1,U2,U3,U4), T1 a1, T2 a2, T3 a3, T4 a4);
+  static EventId ScheduleDestroy (void (*f) (U1,U2,U3,U4), T1 a1, T2 a2, T3 a3, T4 a4);
   /**
    * @param f the function to invoke
    * @param a1 the first argument to pass to the function to invoke
@@ -521,7 +521,7 @@
    */
   template <typename U1, typename U2, typename U3, typename U4, typename U5,
             typename T1, typename T2, typename T3, typename T4, typename T5>
-  static void ScheduleDestroy (void (*f) (U1,U2,U3,U4,U5), T1 a1, T2 a2, T3 a3, T4 a4, T5 a5);
+  static EventId ScheduleDestroy (void (*f) (U1,U2,U3,U4,U5), T1 a1, T2 a2, T3 a3, T4 a4, T5 a5);
 
   /**
    * Remove an event from the event list. 
@@ -611,8 +611,8 @@
 
   static SimulatorPrivate *GetPriv (void);
   static EventId Schedule (Time const &time, EventImpl *event);
-  static void ScheduleDestroy (EventImpl *event);
-  static void ScheduleNow (EventImpl *event);
+  static EventId ScheduleDestroy (EventImpl *event);
+  static EventId ScheduleNow (EventImpl *event);
   static SimulatorPrivate *m_priv;
 };
 
@@ -1061,193 +1061,193 @@
 
 
 template <typename T, typename OBJ>
-void
+EventId
 Simulator::ScheduleNow (void (T::*mem_ptr) (void), OBJ obj) 
 {
-  ScheduleNow (MakeEvent (mem_ptr, obj));
+  return ScheduleNow (MakeEvent (mem_ptr, obj));
 }
 
 
 template <typename T, typename OBJ, 
           typename U1,
           typename T1>
-void
+EventId
 Simulator::ScheduleNow (void (T::*mem_ptr) (U1), OBJ obj, T1 a1) 
 {
-  ScheduleNow (MakeEvent (mem_ptr, obj, a1));
+  return ScheduleNow (MakeEvent (mem_ptr, obj, a1));
 }
 
 template <typename T, typename OBJ, 
           typename U1, typename U2,
           typename T1, typename T2>
-void
+EventId
 Simulator::ScheduleNow (void (T::*mem_ptr) (U1,U2), OBJ obj, T1 a1, T2 a2) 
 {
-  ScheduleNow (MakeEvent (mem_ptr, obj, a1, a2));
+  return ScheduleNow (MakeEvent (mem_ptr, obj, a1, a2));
 }
 
 template <typename T, typename OBJ, 
           typename U1, typename U2, typename U3,
           typename T1, typename T2, typename T3>
-void
+EventId
 Simulator::ScheduleNow (void (T::*mem_ptr) (U1,U2,U3), OBJ obj, T1 a1, T2 a2, T3 a3) 
 {
-  ScheduleNow (MakeEvent (mem_ptr, obj, a1, a2, a3));
+  return ScheduleNow (MakeEvent (mem_ptr, obj, a1, a2, a3));
 }
 
 template <typename T, typename OBJ, 
           typename U1, typename U2, typename U3, typename U4,
           typename T1, typename T2, typename T3, typename T4>
-void
+EventId
 Simulator::ScheduleNow (void (T::*mem_ptr) (U1,U2,U3,U4), OBJ obj, T1 a1, T2 a2, T3 a3, T4 a4) 
 {
-  ScheduleNow (MakeEvent (mem_ptr, obj, a1, a2, a3, a4));
+  return ScheduleNow (MakeEvent (mem_ptr, obj, a1, a2, a3, a4));
 }
 
 template <typename T, typename OBJ, 
           typename U1, typename U2, typename U3, typename U4, typename U5,
           typename T1, typename T2, typename T3, typename T4, typename T5>
-void
+EventId
 Simulator::ScheduleNow (void (T::*mem_ptr) (U1,U2,U3,U4,U5), OBJ obj, 
                         T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) 
 {
-  ScheduleNow (MakeEvent (mem_ptr, obj, a1, a2, a3, a4, a5));
+  return ScheduleNow (MakeEvent (mem_ptr, obj, a1, a2, a3, a4, a5));
 }
 
 template <typename U1,
           typename T1>
-void
+EventId
 Simulator::ScheduleNow (void (*f) (U1), T1 a1) 
 {
-  ScheduleNow (MakeEvent (f, a1));
+  return ScheduleNow (MakeEvent (f, a1));
 }
 
 template <typename U1, typename U2,
           typename T1, typename T2>
-void
+EventId
 Simulator::ScheduleNow (void (*f) (U1,U2), T1 a1, T2 a2) 
 {
-  ScheduleNow (MakeEvent (f, a1, a2));
+  return ScheduleNow (MakeEvent (f, a1, a2));
 }
 
 template <typename U1, typename U2, typename U3,
           typename T1, typename T2, typename T3>
-void
+EventId
 Simulator::ScheduleNow (void (*f) (U1,U2,U3), T1 a1, T2 a2, T3 a3)
 {
-  ScheduleNow (MakeEvent (f, a1, a2, a3));
+  return ScheduleNow (MakeEvent (f, a1, a2, a3));
 }
 
 template <typename U1, typename U2, typename U3, typename U4,
           typename T1, typename T2, typename T3, typename T4>
-void
+EventId
 Simulator::ScheduleNow (void (*f) (U1,U2,U3,U4), T1 a1, T2 a2, T3 a3, T4 a4) 
 {
-  ScheduleNow (MakeEvent (f, a1, a2, a3, a4));
+  return ScheduleNow (MakeEvent (f, a1, a2, a3, a4));
 }
 
 template <typename U1, typename U2, typename U3, typename U4, typename U5,
           typename T1, typename T2, typename T3, typename T4, typename T5>
-void
+EventId
 Simulator::ScheduleNow (void (*f) (U1,U2,U3,U4,U5), T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) 
 {
-  ScheduleNow (MakeEvent (f, a1, a2, a3, a4, a5));
+  return ScheduleNow (MakeEvent (f, a1, a2, a3, a4, a5));
 }
 
 
 
 template <typename T, typename OBJ>
-void
+EventId
 Simulator::ScheduleDestroy (void (T::*mem_ptr) (void), OBJ obj) 
 {
-  ScheduleDestroy (MakeEvent (mem_ptr, obj));
+  return ScheduleDestroy (MakeEvent (mem_ptr, obj));
 }
 
 
 template <typename T, typename OBJ, 
           typename U1,
           typename T1>
-void
+EventId
 Simulator::ScheduleDestroy (void (T::*mem_ptr) (U1), OBJ obj, T1 a1) 
 {
-  ScheduleDestroy (MakeEvent (mem_ptr, obj, a1));
+  return ScheduleDestroy (MakeEvent (mem_ptr, obj, a1));
 }
 
 template <typename T, typename OBJ, 
           typename U1, typename U2,
           typename T1, typename T2>
-void
+EventId
 Simulator::ScheduleDestroy (void (T::*mem_ptr) (U1,U2), OBJ obj, T1 a1, T2 a2) 
 {
-  ScheduleDestroy (MakeEvent (mem_ptr, obj, a1, a2));
+  return ScheduleDestroy (MakeEvent (mem_ptr, obj, a1, a2));
 }
 
 template <typename T, typename OBJ, 
           typename U1, typename U2, typename U3,
           typename T1, typename T2, typename T3>
-void
+EventId
 Simulator::ScheduleDestroy (void (T::*mem_ptr) (U1,U2,U3), OBJ obj, T1 a1, T2 a2, T3 a3) 
 {
-  ScheduleDestroy (MakeEvent (mem_ptr, obj, a1, a2, a3));
+  return ScheduleDestroy (MakeEvent (mem_ptr, obj, a1, a2, a3));
 }
 
 template <typename T, typename OBJ,
           typename U1, typename U2, typename U3, typename U4,
           typename T1, typename T2, typename T3, typename T4>
-void
+EventId
 Simulator::ScheduleDestroy (void (T::*mem_ptr) (U1,U2,U3,U4), OBJ obj, T1 a1, T2 a2, T3 a3, T4 a4) 
 {
-  ScheduleDestroy (MakeEvent (mem_ptr, obj, a1, a2, a3, a4));
+  return ScheduleDestroy (MakeEvent (mem_ptr, obj, a1, a2, a3, a4));
 }
 
 template <typename T, typename OBJ, 
           typename U1, typename U2, typename U3, typename U4, typename U5,
           typename T1, typename T2, typename T3, typename T4, typename T5>
-void
+EventId
 Simulator::ScheduleDestroy (void (T::*mem_ptr) (U1,U2,U3,U4,U5), OBJ obj, 
                             T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) 
 {
-  ScheduleDestroy (MakeEvent (mem_ptr, obj, a1, a2, a3, a4, a5));
+  return ScheduleDestroy (MakeEvent (mem_ptr, obj, a1, a2, a3, a4, a5));
 }
 
 template <typename U1,
           typename T1>
-void
+EventId
 Simulator::ScheduleDestroy (void (*f) (U1), T1 a1) 
 {
-  ScheduleDestroy (MakeEvent (f, a1));
+  return ScheduleDestroy (MakeEvent (f, a1));
 }
 
 template <typename U1, typename U2,
           typename T1, typename T2>
-void
+EventId
 Simulator::ScheduleDestroy (void (*f) (U1,U2), T1 a1, T2 a2) 
 {
-  ScheduleDestroy (MakeEvent (f, a1, a2));
+  return ScheduleDestroy (MakeEvent (f, a1, a2));
 }
 
 template <typename U1, typename U2, typename U3,
           typename T1, typename T2, typename T3>
-void
+EventId
 Simulator::ScheduleDestroy (void (*f) (U1,U2,U3), T1 a1, T2 a2, T3 a3)
 {
-  ScheduleDestroy (MakeEvent (f, a1, a2, a3));
+  return ScheduleDestroy (MakeEvent (f, a1, a2, a3));
 }
 
 template <typename U1, typename U2, typename U3, typename U4,
           typename T1, typename T2, typename T3, typename T4>
-void
+EventId
 Simulator::ScheduleDestroy (void (*f) (U1,U2,U3,U4), T1 a1, T2 a2, T3 a3, T4 a4) 
 {
-  ScheduleDestroy (MakeEvent (f, a1, a2, a3, a4));
+  return ScheduleDestroy (MakeEvent (f, a1, a2, a3, a4));
 }
 
 template <typename U1, typename U2, typename U3, typename U4, typename U5,
           typename T1, typename T2, typename T3, typename T4, typename T5>
-void
+EventId
 Simulator::ScheduleDestroy (void (*f) (U1,U2,U3,U4,U5), T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) 
 {
-  ScheduleDestroy (MakeEvent (f, a1, a2, a3, a4, a5));
+  return ScheduleDestroy (MakeEvent (f, a1, a2, a3, a4, a5));
 }
 
 }; // namespace ns3