int Ts2::Network::RouteManager::CancelDataPackets(u32 srcVtId) { int err = 0; { MutexAutoLock lock(&mutex); state.clients++; if (state.stop == STOP_STATE_STOPPING) { LOG_WARN("RouteManager[%p]: Method called after Stop", this); } // Removing an element from the middle of a queue maybe expensive. // Thus, instead of removing it, we will simply replace the pointer to a Packet obj with a NULL pointer. // Dequeue code (in packetThreadMain()) will check the pointer value and ignore if NULL. std::deque<std::pair<Packet*, VPLTime_t> >::iterator it; for (it = packetQueue.begin(); it != packetQueue.end(); it++) { Packet *packet = it->first; if (packet && (packet->GetPktType() == TS_PKT_DATA) && (packet->GetSrcVtId() == srcVtId)) { delete packet; // destroy Packet obj it->first = NULL; // replace pointer with NULL pointer } } } { // If the worker thread is trying to send, wait until it is done. // This is necessary, since it may be currently processing a packet that // would have been cancelled by the loop above. MutexAutoLock lock(&mutex_packetThreadSending); while (packetThreadSending) { err = VPLCond_TimedWait(&cond_packetThreadSending, &mutex_packetThreadSending, VPL_TIMEOUT_NONE); if (err) { LOG_ERROR("RouteManager[%p]: CondVar failed: err %d", this, err); err = 0; // Reset error and exit. break; } } } { MutexAutoLock lock(&mutex); state.clients--; if (state.clients == 0) { VPLCond_Broadcast(&cond_state_noClients); } } return err; }