From 08b0d1ce458520dbe541db5b275fb288b203c35f Mon Sep 17 00:00:00 2001 From: "Andrew D. Zonenberg" Date: Sun, 1 Sep 2024 22:37:54 -0700 Subject: [PATCH] Make sure that late-arriving waveforms are added to history before we detach them from the oscilloscope (prevents Vulkan handle leaks) --- src/ngscopeclient/Session.cpp | 48 ++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/src/ngscopeclient/Session.cpp b/src/ngscopeclient/Session.cpp index 2e4d74fb..7c117a16 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,10 +176,25 @@ 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(); + //Add any latecomer waveforms to history to make sure we know who owns them + if(g_waveformReadyEvent.Peek()) + { + LogTrace("Found late waveform, adding to history before clearing it\n"); + + vector> scopes; + set> groups; + { + lock_guard lock3(m_recentlyTriggeredScopeMutex); + for(auto scope : m_recentlyTriggeredScopes) + scopes.push_back(scope); + m_recentlyTriggeredScopes.clear(); + + groups = m_recentlyTriggeredGroups; + m_recentlyTriggeredGroups.clear(); + + m_history.AddHistory(scopes); + } + } //Delete scopes once we've terminated the threads //Detach waveforms before we destroy the scope, since history owns them @@ -197,6 +210,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();