From e67a29f5b6456b3eea765b0dc16d511f89d6b887 Mon Sep 17 00:00:00 2001 From: vsonnier Date: Sat, 12 Aug 2017 11:30:32 +0200 Subject: [PATCH] Don't get stuck when closing application just because some Demodulators refuse to die --- src/CubicSDR.cpp | 2 +- src/demod/DemodulatorMgr.cpp | 26 ++++++++++++++++++++++++-- src/demod/DemodulatorMgr.h | 4 +++- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/CubicSDR.cpp b/src/CubicSDR.cpp index 1abcaee..044569e 100644 --- a/src/CubicSDR.cpp +++ b/src/CubicSDR.cpp @@ -405,7 +405,7 @@ int CubicSDR::OnExit() { std::cout << "Terminating All Demodulators.." << std::endl; demodMgr.terminateAll(); //wait for effective death of all demodulators before continuing. - demodMgr.garbageCollect(true); + demodMgr.garbageCollect(true, 3000); std::cout << "Terminating Visual Processor threads.." << std::endl; spectrumVisualThread->terminate(); diff --git a/src/demod/DemodulatorMgr.cpp b/src/demod/DemodulatorMgr.cpp index 7f0cd14..f1ea21e 100644 --- a/src/demod/DemodulatorMgr.cpp +++ b/src/demod/DemodulatorMgr.cpp @@ -278,8 +278,23 @@ DemodulatorInstance *DemodulatorMgr::getLastDemodulatorWith(const std::string& t return nullptr; } -void DemodulatorMgr::garbageCollect(bool forcedGC) { +void DemodulatorMgr::garbageCollect(bool forcedGC, int maxWaitForTerminationMs) { +#define SPIN_WAIT_SLEEP_MS 5 + + //this is a stupid busy plus sleep loop + int nbCyclesToWait = 0; + + if (maxWaitForTerminationMs <= 0) { + nbCyclesToWait = std::numeric_limits::max(); + } + else { + + nbCyclesToWait = (maxWaitForTerminationMs / SPIN_WAIT_SLEEP_MS) + 1; + } + + int currentWaitCycle = 0; + std::lock_guard < std::mutex > lock(deleted_demods_busy); while (!demods_deleted.empty()) { @@ -306,7 +321,14 @@ void DemodulatorMgr::garbageCollect(bool forcedGC) { } } //end while //stupid busy-wait loop - std::this_thread::sleep_for(std::chrono::milliseconds(5)); + std::this_thread::sleep_for(std::chrono::milliseconds(SPIN_WAIT_SLEEP_MS)); + + currentWaitCycle++; + + if (currentWaitCycle >= nbCyclesToWait) { + std::cout << "ERROR: DemodulatorMgr::garbageCollect() has not terminated in time ! (> " << (currentWaitCycle * SPIN_WAIT_SLEEP_MS) << " ms)" << std::endl << std::flush; + return; + } } //end while not empty } diff --git a/src/demod/DemodulatorMgr.h b/src/demod/DemodulatorMgr.h index 906a9d7..462920d 100644 --- a/src/demod/DemodulatorMgr.h +++ b/src/demod/DemodulatorMgr.h @@ -73,7 +73,9 @@ public: //all deleted demodulators are effectively GCed. //else: (default) the method test for effective termination //and GC one demod per call. - void garbageCollect(bool forcedGC = false); + // if forcedGC = true and maxWaitForTerminationMs > 0, do not + //block the method more than maxWaitForTerminationMs millisecs before returning. + void garbageCollect(bool forcedGC = false, int maxWaitForTerminationMs = 0); private: