Don't get stuck when closing application just because some Demodulators refuse to die

This commit is contained in:
vsonnier 2017-08-12 11:30:32 +02:00
parent 33aa0cade6
commit e67a29f5b6
3 changed files with 28 additions and 4 deletions

View File

@ -405,7 +405,7 @@ int CubicSDR::OnExit() {
std::cout << "Terminating All Demodulators.." << std::endl; std::cout << "Terminating All Demodulators.." << std::endl;
demodMgr.terminateAll(); demodMgr.terminateAll();
//wait for effective death of all demodulators before continuing. //wait for effective death of all demodulators before continuing.
demodMgr.garbageCollect(true); demodMgr.garbageCollect(true, 3000);
std::cout << "Terminating Visual Processor threads.." << std::endl; std::cout << "Terminating Visual Processor threads.." << std::endl;
spectrumVisualThread->terminate(); spectrumVisualThread->terminate();

View File

@ -278,8 +278,23 @@ DemodulatorInstance *DemodulatorMgr::getLastDemodulatorWith(const std::string& t
return nullptr; 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<int>::max();
}
else {
nbCyclesToWait = (maxWaitForTerminationMs / SPIN_WAIT_SLEEP_MS) + 1;
}
int currentWaitCycle = 0;
std::lock_guard < std::mutex > lock(deleted_demods_busy); std::lock_guard < std::mutex > lock(deleted_demods_busy);
while (!demods_deleted.empty()) { while (!demods_deleted.empty()) {
@ -306,7 +321,14 @@ void DemodulatorMgr::garbageCollect(bool forcedGC) {
} }
} //end while } //end while
//stupid busy-wait loop //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 } //end while not empty
} }

View File

@ -73,7 +73,9 @@ public:
//all deleted demodulators are effectively GCed. //all deleted demodulators are effectively GCed.
//else: (default) the method test for effective termination //else: (default) the method test for effective termination
//and GC one demod per call. //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: private: