src/devices/emu/emu-net-device.cc
changeset 5829 d3f02a8dee76
parent 5822 c16bcd1c6647
child 5834 8481618b577f
--- a/src/devices/emu/emu-net-device.cc	Tue Dec 01 18:34:11 2009 +0300
+++ b/src/devices/emu/emu-net-device.cc	Wed Dec 02 11:25:29 2009 -0800
@@ -189,11 +189,8 @@
 
 EmuNetDevice::~EmuNetDevice ()
 {
-  if (m_packetBuffer)
-    {
-      delete [] m_packetBuffer;
-      m_packetBuffer = 0;
-    }
+  delete [] m_packetBuffer;
+  m_packetBuffer = 0;
 }
 
 void 
@@ -229,20 +226,6 @@
   //
   Simulator::Cancel (m_startEvent);
   m_startEvent = Simulator::Schedule (tStart, &EmuNetDevice::StartDevice, this);
-
-  //
-  // We're going to need a pointer to the realtime simulator implementation.
-  // It's important to remember that access to that implementation may happen 
-  // in a completely different thread than the simulator is running in.  We are
-  // talking about multiple threads here, so it is very, very dangerous to do 
-  // any kind of reference couning on a shared object.  So what we are going to 
-  // do is to get a reference to the realtime simulator and then save a raw 
-  // pointer to that implementation for use by the other threads.  We must not
-  // free this pointer or we may delete the simulator out from under us an 
-  // everyone else.
-  //
-  Ptr<RealtimeSimulatorImpl> impl = DynamicCast<RealtimeSimulatorImpl> (Simulator::GetImplementation ());
-  m_rtImpl = GetPointer (impl);
 }
 
   void
@@ -269,7 +252,28 @@
       NS_FATAL_ERROR ("EmuNetDevice::StartDevice(): Device is already started");
     }
 
+  //
+  // We're going to need a pointer to the realtime simulator implementation.
+  // It's important to remember that access to that implementation may happen 
+  // in a completely different thread than the simulator is running in (we're 
+  // going to spin up that thread below).  We are talking about multiple threads
+  // here, so it is very, very dangerous to do any kind of reference couning on
+  // a shared object that is unaware of what is happening.  What we are going to 
+  // do to address that is to get a reference to the realtime simulator here 
+  // where we are running in the context of a running simulator scheduler --
+  // recall we did a Simulator::Schedule of this method above.  We get the
+  // simulator implementation pointer in a single-threaded way and save the
+  // underlying raw pointer for use by the (other) read thread.  We must not
+  // free this pointer or we may delete the simulator out from under us an 
+  // everyone else.  We assume that the simulator implementation cannot be 
+  // replaced while the emu device is running and so will remain valid through
+  // the time during which the read thread is running.
+  //
+  Ptr<RealtimeSimulatorImpl> impl = DynamicCast<RealtimeSimulatorImpl> (Simulator::GetImplementation ());
+  m_rtImpl = GetPointer (impl);
+
   NS_LOG_LOGIC ("Creating socket");
+
   //
   // Call out to a separate process running as suid root in order to get a raw 
   // socket.  We do this to avoid having the entire simulation running as root.