diff -r 533be42b3c7f src/devices/tap-bridge/tap-bridge.cc --- a/src/devices/tap-bridge/tap-bridge.cc Fri Apr 30 13:10:23 2010 -0400 +++ b/src/devices/tap-bridge/tap-bridge.cc Fri Apr 30 11:03:59 2010 -0700 @@ -233,6 +233,14 @@ CreateTap (); // + // We're going to spin up a thread soon, so we need to make sure we have + // a way to tear down that thread when the simulation stops. Do this by + // scheduling a "destroy time" method to make sure the thread exits before + // proceeding. + // + Simulator::ScheduleDestroy (&TapBridge::StopTapDevice, this); + + // // Now spin up a read thread to read packets from the tap device. // NS_ABORT_MSG_IF (m_readThread != 0,"TapBridge::StartTapDevice(): Receive thread is already running"); @@ -247,14 +255,28 @@ { NS_LOG_FUNCTION_NOARGS (); - close (m_sock); - m_sock = -1; + // + // If the socket is open, then close it. This will triger any running read + // thread to exit. + // + if (m_sock != -1) + { + close (m_sock); + m_sock = -1; + } - NS_ASSERT_MSG (m_readThread != 0, "TapBridge::StopTapDevice(): Receive thread is not running"); - - NS_LOG_LOGIC ("Joining read thread"); - m_readThread->Join (); - m_readThread = 0; + // + // If a read thread is running, then we just told it to exit by closing its + // socket. Instead of hoping for the best, we hang out until the thread + // actually exits, in case it decides it needs to do something ns-3-ish + // before returning. + // + if (m_readThread != 0) + { + NS_LOG_LOGIC ("Joining read thread"); + m_readThread->Join (); + m_readThread = 0; + } } void