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;
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();

View File

@ -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<int>::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
}

View File

@ -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: