|
233 |
CreateTap (); |
233 |
CreateTap (); |
234 |
|
234 |
|
235 |
// |
235 |
// |
|
|
236 |
// We're going to spin up a thread soon, so we need to make sure we have |
237 |
// a way to tear down that thread when the simulation stops. Do this by |
238 |
// scheduling a "destroy time" method to make sure the thread exits before |
239 |
// proceeding. |
240 |
// |
241 |
Simulator::ScheduleDestroy (&TapBridge::StopTapDevice, this); |
242 |
|
243 |
// |
236 |
// Now spin up a read thread to read packets from the tap device. |
244 |
// Now spin up a read thread to read packets from the tap device. |
237 |
// |
245 |
// |
238 |
NS_ABORT_MSG_IF (m_readThread != 0,"TapBridge::StartTapDevice(): Receive thread is already running"); |
246 |
NS_ABORT_MSG_IF (m_readThread != 0,"TapBridge::StartTapDevice(): Receive thread is already running"); |
|
247 |
{ |
255 |
{ |
248 |
NS_LOG_FUNCTION_NOARGS (); |
256 |
NS_LOG_FUNCTION_NOARGS (); |
249 |
|
257 |
|
250 |
close (m_sock); |
258 |
// |
251 |
m_sock = -1; |
259 |
// If the socket is open, then close it. This will triger any running read |
|
|
260 |
// thread to exit. |
261 |
// |
262 |
if (m_sock != -1) |
263 |
{ |
264 |
close (m_sock); |
265 |
m_sock = -1; |
266 |
} |
252 |
|
267 |
|
253 |
NS_ASSERT_MSG (m_readThread != 0, "TapBridge::StopTapDevice(): Receive thread is not running"); |
268 |
// |
254 |
|
269 |
// If a read thread is running, then we just told it to exit by closing its |
255 |
NS_LOG_LOGIC ("Joining read thread"); |
270 |
// socket. Instead of hoping for the best, we hang out until the thread |
256 |
m_readThread->Join (); |
271 |
// actually exits, in case it decides it needs to do something ns-3-ish |
257 |
m_readThread = 0; |
272 |
// before returning. |
|
|
273 |
// |
274 |
if (m_readThread != 0) |
275 |
{ |
276 |
NS_LOG_LOGIC ("Joining read thread"); |
277 |
m_readThread->Join (); |
278 |
m_readThread = 0; |
279 |
} |
258 |
} |
280 |
} |
259 |
|
281 |
|
260 |
void |
282 |
void |