--- 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.