bool PacketSender::threadedProcess() { bool hasSlept = false; if (_lastSendTime == 0) { _lastSendTime = usecTimestampNow(); } // in threaded mode, we keep running and just empty our packet queue sleeping enough to keep our PPS on target while (_packets.size() > 0) { // Recalculate our SEND_INTERVAL_USECS each time, in case the caller has changed it on us.. int packetsPerSecondTarget = (_packetsPerSecond > MINIMUM_PACKETS_PER_SECOND) ? _packetsPerSecond : MINIMUM_PACKETS_PER_SECOND; quint64 intervalBetweenSends = USECS_PER_SECOND / packetsPerSecondTarget; quint64 sleepInterval = (intervalBetweenSends > SENDING_INTERVAL_ADJUST) ? intervalBetweenSends - SENDING_INTERVAL_ADJUST : intervalBetweenSends; // We'll sleep before we send, this way, we can set our last send time to be our ACTUAL last send time quint64 now = usecTimestampNow(); quint64 elapsed = now - _lastSendTime; int usecToSleep = sleepInterval - elapsed; // If we've never sent, or it's been a long time since we sent, then our elapsed time will be quite large // and therefore usecToSleep will be less than 0 and we won't sleep before sending... if (usecToSleep > 0) { if (usecToSleep > MAX_SLEEP_INTERVAL) { usecToSleep = MAX_SLEEP_INTERVAL; } usleep(usecToSleep); hasSlept = true; } // call our non-threaded version of ourselves bool keepRunning = nonThreadedProcess(); if (!keepRunning) { break; } } // if threaded and we haven't slept? We want to wait for our consumer to signal us with new packets if (!hasSlept) { // wait till we have packets _waitingOnPacketsMutex.lock(); _hasPackets.wait(&_waitingOnPacketsMutex); _waitingOnPacketsMutex.unlock(); } return isStillRunning(); }
bool PacketSender::threadedProcess() { bool hasSlept = false; if (_lastSendTime == 0) { _lastSendTime = usecTimestampNow(); } // in threaded mode, we keep running and just empty our packet queue sleeping enough to keep our PPS on target while (_packets.size() > 0) { // Recalculate our SEND_INTERVAL_USECS each time, in case the caller has changed it on us.. int packetsPerSecondTarget = (_packetsPerSecond > MINIMUM_PACKETS_PER_SECOND) ? _packetsPerSecond : MINIMUM_PACKETS_PER_SECOND; quint64 intervalBetweenSends = USECS_PER_SECOND / packetsPerSecondTarget; quint64 sleepInterval = (intervalBetweenSends > SENDING_INTERVAL_ADJUST) ? intervalBetweenSends - SENDING_INTERVAL_ADJUST : intervalBetweenSends; // We'll sleep before we send, this way, we can set our last send time to be our ACTUAL last send time quint64 now = usecTimestampNow(); quint64 elapsed = now - _lastSendTime; int usecToSleep = sleepInterval - elapsed; // If we've never sent, or it's been a long time since we sent, then our elapsed time will be quite large // and therefore usecToSleep will be less than 0 and we won't sleep before sending... if (usecToSleep > 0) { if (usecToSleep > MAX_SLEEP_INTERVAL) { usecToSleep = MAX_SLEEP_INTERVAL; } usleep(usecToSleep); hasSlept = true; } // call our non-threaded version of ourselves bool keepRunning = nonThreadedProcess(); if (!keepRunning) { break; } } // if threaded and we haven't slept? We want to sleep a little so we don't hog the CPU, but // we don't want to sleep too long because how ever much we sleep will delay any future unsent // packets that arrive while we're sleeping. So we sleep 1/2 of our target fps interval if (!hasSlept) { usleep(MINIMAL_SLEEP_INTERVAL); } return isStillRunning(); }
bool PacketSender::process() { if (isThreaded()) { return threadedProcess(); } return nonThreadedProcess(); }