diff --git a/src/ngscopeclient/HistoryManager.cpp b/src/ngscopeclient/HistoryManager.cpp index 6c35f667..23add750 100644 --- a/src/ngscopeclient/HistoryManager.cpp +++ b/src/ngscopeclient/HistoryManager.cpp @@ -219,7 +219,7 @@ void HistoryManager::LoadEmptyHistoryToSession(Session& session) @param scopes The instruments to add @param deleteOld True to delete old data that rolled off the end of the history buffer - Set false when loading waveforms from a sessio + Set false when loading waveforms from a session @param pin True to pin into history @param nick Nickname */ diff --git a/src/ngscopeclient/Session.cpp b/src/ngscopeclient/Session.cpp index 2e4d74fb..9510ea82 100644 --- a/src/ngscopeclient/Session.cpp +++ b/src/ngscopeclient/Session.cpp @@ -112,25 +112,23 @@ void Session::ClearBackgroundThreads() { LogTrace("Clearing background threads\n"); - //Signal our threads to exit - //The sooner we do this, the faster they'll exit. - m_shuttingDown = true; - //Stop the trigger so there's no pending waveforms - StopTrigger(); + StopTrigger(true); + + //Shut down instrument threads. + //This has to happen before we terminate the WaveformThread, to avoid waveforms getting stuck + //which have been acquired but not processed + for(auto it : m_instrumentStates) + it.second->Close(); //Clear our trigger state //Important to signal the WaveformProcessingThread so it doesn't block waiting on response that's not going to come - m_triggerArmed = false; g_waveformReadyEvent.Clear(); g_rerenderDoneEvent.Clear(); g_waveformProcessedEvent.Signal(); - //Shut down instrument threads - for(auto it : m_instrumentStates) - it.second->Close(); - - //Block until our processing threads exit + //Signal our other worker threads to exit, then wait until they do so + m_shuttingDown = true; if(m_waveformThread) m_waveformThread->join(); m_waveformThread = nullptr; @@ -178,13 +176,10 @@ void Session::Clear() //Might be redundant. lock_guard lock2(m_scopeMutex); - //Clear history before destroying scopes. - //This ordering is important since waveforms removed from history get pushed into the WaveformPool of the scopes, - //so the scopes must not have been destroyed yet. - m_history.clear(); - //Delete scopes once we've terminated the threads //Detach waveforms before we destroy the scope, since history owns them + //(but make sure they're actually *in* history first!) + m_history.AddHistory(m_oscilloscopes); for(auto scope : m_oscilloscopes) { for(size_t i=0; iGetChannelCount(); i++) @@ -197,6 +192,11 @@ void Session::Clear() } } + //Clear history before destroying scopes (but after detaching waveforms) + //This ordering is important since waveforms removed from history get pushed into the WaveformPool of the scopes, + //so the scopes must not have been destroyed yet. + m_history.clear(); + m_oscilloscopes.clear(); m_psus.clear(); m_loads.clear();