From 0e016838b4029e7ceabf00405fe7f7006bd242c8 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 27 Jan 2016 10:17:08 -0800 Subject: [PATCH 1/6] tweak size of values in AudioMixer --- assignment-client/src/audio/AudioMixer.cpp | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index bcd9478700..d85e1d137b 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -680,11 +680,11 @@ void AudioMixer::domainSettingsRequestComplete() { void AudioMixer::broadcastMixes() { auto nodeList = DependencyManager::get(); - int nextFrame = 0; + int64_t nextFrame = 0; QElapsedTimer timer; timer.start(); - int usecToSleep = AudioConstants::NETWORK_FRAME_USECS; + int64_t usecToSleep = AudioConstants::NETWORK_FRAME_USECS; const int TRAILING_AVERAGE_FRAMES = 100; int framesSinceCutoffEvent = TRAILING_AVERAGE_FRAMES; @@ -826,12 +826,7 @@ void AudioMixer::broadcastMixes() { break; } - usecToSleep = (++nextFrame * AudioConstants::NETWORK_FRAME_USECS) - timer.nsecsElapsed() / 1000; // ns to us - - if (usecToSleep > int(USECS_PER_SECOND)) { - qDebug() << "DANGER: amount to sleep is" << usecToSleep; - qDebug() << "NextFrame is" << nextFrame << "and timer nsecs elapsed is" << timer.nsecsElapsed(); - } + usecToSleep = (++nextFrame * AudioConstants::NETWORK_FRAME_USECS) - (timer.nsecsElapsed() / 1000); if (usecToSleep > 0) { usleep(usecToSleep); From e50e75cba74ce4bdbb2dd77c13efda8f4d1d3f6e Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 27 Jan 2016 11:41:23 -0800 Subject: [PATCH 2/6] drop assignment even if DDOS locks NL thread --- libraries/networking/src/NodeList.cpp | 3 +++ libraries/networking/src/NodeList.h | 1 + libraries/networking/src/ThreadedAssignment.cpp | 13 ++++++++++++- libraries/networking/src/ThreadedAssignment.h | 2 ++ 4 files changed, 18 insertions(+), 1 deletion(-) diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index b0cd8cce39..16277caace 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -490,6 +490,9 @@ void NodeList::processDomainServerList(QSharedPointer message) // this is a packet from the domain server, reset the count of un-replied check-ins _numNoReplyDomainCheckIns = 0; + // emit our signal so listeners know we just heard from the DS + emit receivedDomainServerList(); + DependencyManager::get()->flagTimeForConnectionStep(LimitedNodeList::ConnectionStep::ReceiveDSList); QDataStream packetStream(message->getMessage()); diff --git a/libraries/networking/src/NodeList.h b/libraries/networking/src/NodeList.h index 171ea0c6a7..4b196d5f7b 100644 --- a/libraries/networking/src/NodeList.h +++ b/libraries/networking/src/NodeList.h @@ -87,6 +87,7 @@ public slots: signals: void limitOfSilentDomainCheckInsReached(); + void receivedDomainServerList(); private slots: void stopKeepalivePingTimer(); void sendPendingDSPathQuery(); diff --git a/libraries/networking/src/ThreadedAssignment.cpp b/libraries/networking/src/ThreadedAssignment.cpp index 303755c8f3..10f9c03cab 100644 --- a/libraries/networking/src/ThreadedAssignment.cpp +++ b/libraries/networking/src/ThreadedAssignment.cpp @@ -30,6 +30,10 @@ ThreadedAssignment::ThreadedAssignment(ReceivedMessage& message) : connect(&_domainServerTimer, &QTimer::timeout, this, &ThreadedAssignment::checkInWithDomainServerOrExit); _domainServerTimer.setInterval(DOMAIN_SERVER_CHECK_IN_MSECS); + + // if the NL tells us we got a DS response, clear our member variable of queued check-ins + auto nodeList = DependencyManager::get(); + connect(nodeList.data(), &NodeList::receivedDomainServerList, this, &ThreadedAssignment::clearQueuedCheckIns); } void ThreadedAssignment::setFinished(bool isFinished) { @@ -103,11 +107,18 @@ void ThreadedAssignment::sendStatsPacket() { } void ThreadedAssignment::checkInWithDomainServerOrExit() { - if (DependencyManager::get()->getNumNoReplyDomainCheckIns() == MAX_SILENT_DOMAIN_SERVER_CHECK_INS) { + qDebug() << "WE ARE AT" << _numQueuedCheckIns << "queued check-ins"; + + // verify that the number of queued check-ins is not >= our max + // the number of queued check-ins is cleared anytime we get a response from the domain-server + if (_numQueuedCheckIns >= MAX_SILENT_DOMAIN_SERVER_CHECK_INS) { setFinished(true); } else { auto nodeList = DependencyManager::get(); QMetaObject::invokeMethod(nodeList.data(), "sendDomainServerCheckIn"); + + // increase the number of queued check ins + _numQueuedCheckIns++; } } diff --git a/libraries/networking/src/ThreadedAssignment.h b/libraries/networking/src/ThreadedAssignment.h index 42d4903c2f..13b9b5bf79 100644 --- a/libraries/networking/src/ThreadedAssignment.h +++ b/libraries/networking/src/ThreadedAssignment.h @@ -33,6 +33,7 @@ public slots: virtual void run() = 0; Q_INVOKABLE virtual void stop() { setFinished(true); } virtual void sendStatsPacket(); + void clearQueuedCheckIns() { _numQueuedCheckIns = 0; } signals: void finished(); @@ -42,6 +43,7 @@ protected: bool _isFinished; QTimer _domainServerTimer; QTimer _statsTimer; + int _numQueuedCheckIns { 0 }; protected slots: void domainSettingsRequestFailed(); From 5551a052617898eb948a2ff9700f1698f3bce5ac Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 27 Jan 2016 11:49:21 -0800 Subject: [PATCH 3/6] removed debug for queued check-ins --- libraries/networking/src/ThreadedAssignment.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/libraries/networking/src/ThreadedAssignment.cpp b/libraries/networking/src/ThreadedAssignment.cpp index 10f9c03cab..4f7ea76b56 100644 --- a/libraries/networking/src/ThreadedAssignment.cpp +++ b/libraries/networking/src/ThreadedAssignment.cpp @@ -107,8 +107,6 @@ void ThreadedAssignment::sendStatsPacket() { } void ThreadedAssignment::checkInWithDomainServerOrExit() { - qDebug() << "WE ARE AT" << _numQueuedCheckIns << "queued check-ins"; - // verify that the number of queued check-ins is not >= our max // the number of queued check-ins is cleared anytime we get a response from the domain-server if (_numQueuedCheckIns >= MAX_SILENT_DOMAIN_SERVER_CHECK_INS) { From c91f8c7685acd28c516e10afd108a627f1f11a6b Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 27 Jan 2016 11:50:13 -0800 Subject: [PATCH 4/6] add debug for DDOS AC drop --- libraries/networking/src/ThreadedAssignment.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/networking/src/ThreadedAssignment.cpp b/libraries/networking/src/ThreadedAssignment.cpp index 4f7ea76b56..9277aa70cc 100644 --- a/libraries/networking/src/ThreadedAssignment.cpp +++ b/libraries/networking/src/ThreadedAssignment.cpp @@ -110,6 +110,8 @@ void ThreadedAssignment::checkInWithDomainServerOrExit() { // verify that the number of queued check-ins is not >= our max // the number of queued check-ins is cleared anytime we get a response from the domain-server if (_numQueuedCheckIns >= MAX_SILENT_DOMAIN_SERVER_CHECK_INS) { + qDebug() << "At least" << MAX_SILENT_DOMAIN_SERVER_CHECK_INS << "have been queued without a response from domain-server" + << "Stopping the current assignment"; setFinished(true); } else { auto nodeList = DependencyManager::get(); From 8d17df338bcb90934cf92b39500c7c6739f35ed5 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 27 Jan 2016 12:09:39 -0800 Subject: [PATCH 5/6] allow AIM event processing during repeated injection --- libraries/audio/src/AudioInjectorManager.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/libraries/audio/src/AudioInjectorManager.cpp b/libraries/audio/src/AudioInjectorManager.cpp index 2327bda0e7..f6f4dc58bf 100644 --- a/libraries/audio/src/AudioInjectorManager.cpp +++ b/libraries/audio/src/AudioInjectorManager.cpp @@ -79,6 +79,11 @@ void AudioInjectorManager::run() { if (_injectors.size() > 0) { // loop through the injectors in the map and send whatever frames need to go out auto front = _injectors.top(); + + // create an InjectorQueue to hold injectors to be queued + // this allows us to call processEvents even if a single injector wants to be re-queued immediately + InjectorQueue holdingQueue; + while (_injectors.size() > 0 && front.first <= usecTimestampNow()) { // either way we're popping this injector off - get a copy first auto injector = front.second; @@ -89,8 +94,8 @@ void AudioInjectorManager::run() { auto nextCallDelta = injector->injectNextFrame(); if (nextCallDelta >= 0 && !injector->isFinished()) { - // re-enqueue the injector with the correct timing - _injectors.emplace(usecTimestampNow() + nextCallDelta, injector); + // enqueue the injector with the correct timing in our holding queue + holdingQueue.emplace(usecTimestampNow() + nextCallDelta, injector); } } @@ -101,6 +106,12 @@ void AudioInjectorManager::run() { break; } } + + // if there are injectors in the holding queue, push them to our persistent queue now + while (!holdingQueue.empty()) { + _injectors.push(holdingQueue.top()); + holdingQueue.pop(); + } } } else { From 20cfe800363984b032e6e6b641f8494dcbd9348e Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 27 Jan 2016 15:25:23 -0800 Subject: [PATCH 6/6] use a vector instead of priority queue to avoid double sort --- libraries/audio/src/AudioInjectorManager.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/libraries/audio/src/AudioInjectorManager.cpp b/libraries/audio/src/AudioInjectorManager.cpp index f6f4dc58bf..032ad71145 100644 --- a/libraries/audio/src/AudioInjectorManager.cpp +++ b/libraries/audio/src/AudioInjectorManager.cpp @@ -82,7 +82,8 @@ void AudioInjectorManager::run() { // create an InjectorQueue to hold injectors to be queued // this allows us to call processEvents even if a single injector wants to be re-queued immediately - InjectorQueue holdingQueue; + std::vector heldInjectors; + heldInjectors.reserve(_injectors.size()); while (_injectors.size() > 0 && front.first <= usecTimestampNow()) { // either way we're popping this injector off - get a copy first @@ -95,7 +96,7 @@ void AudioInjectorManager::run() { if (nextCallDelta >= 0 && !injector->isFinished()) { // enqueue the injector with the correct timing in our holding queue - holdingQueue.emplace(usecTimestampNow() + nextCallDelta, injector); + heldInjectors.emplace(heldInjectors.end(), usecTimestampNow() + nextCallDelta, injector); } } @@ -108,9 +109,9 @@ void AudioInjectorManager::run() { } // if there are injectors in the holding queue, push them to our persistent queue now - while (!holdingQueue.empty()) { - _injectors.push(holdingQueue.top()); - holdingQueue.pop(); + while (!heldInjectors.empty()) { + _injectors.push(heldInjectors.back()); + heldInjectors.pop_back(); } }