1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-06-15 15:49:36 +02:00

Check for Updates dialog will not interrupt recordings

This commit is contained in:
Paul Licameli 2021-06-22 20:08:41 -04:00 committed by Dmitry Vedenko
parent ebcb780197
commit a8afea5a75
3 changed files with 58 additions and 5 deletions

View File

@ -1823,6 +1823,34 @@ int AudioIO::StartStream(const TransportTracks &tracks,
return mStreamToken;
}
void AudioIO::CallAfterRecording(PostRecordingAction action)
{
if (!action)
return;
{
std::lock_guard<std::mutex> guard{ mPostRecordingActionMutex };
if (mPostRecordingAction) {
// Enqueue it, even if perhaps not still recording,
// but it wasn't cleared yet
mPostRecordingAction = [
prevAction = std::move(mPostRecordingAction),
nextAction = std::move(action)
]{ prevAction(); nextAction(); };
return;
}
else if (mPortStreamV19 && mNumCaptureChannels > 0) {
mPostRecordingAction = std::move(action);
return;
}
}
// Don't delay it except until idle time.
// (Recording might start between now and then, but won't go far before
// the action is done. So the system isn't bulletproof yet.)
wxTheApp->CallAfter(std::move(action));
}
bool AudioIO::AllocateBuffers(
const AudioIOStartStreamOptions &options,
const TransportTracks &tracks, double t0, double t1, double sampleRate,
@ -2416,6 +2444,20 @@ void AudioIO::StopStream()
if (pListener && mNumCaptureChannels > 0)
pListener->OnAudioIOStopRecording();
wxTheApp->CallAfter([this]{
if (mPortStreamV19 && mNumCaptureChannels > 0)
// Recording was restarted between StopStream and idle time
// So the actions can keep waiting
return;
// In case some other thread was waiting on the mutex too:
std::this_thread::yield();
std::lock_guard<std::mutex> guard{ mPostRecordingActionMutex };
if (mPostRecordingAction) {
mPostRecordingAction();
mPostRecordingAction = {};
}
});
//
// Only set token to 0 after we're totally finished with everything
//

View File

@ -18,9 +18,9 @@
#include "AudioIOBase.h" // to inherit
#include "PlaybackSchedule.h" // member variable
#include <functional>
#include <memory>
#include <mutex>
#include <utility>
#include <wx/atomic.h> // member variable
@ -621,6 +621,12 @@ public:
* by the specified amount from where it is now */
void SeekStream(double seconds) { mSeek = seconds; }
using PostRecordingAction = std::function<void()>;
//! Enqueue action for main thread idle time, not before the end of any recording in progress
/*! This may be called from non-main threads */
void CallAfterRecording(PostRecordingAction action);
#ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
bool IsScrubbing() const { return IsBusy() && mScrubState != 0; }
@ -787,6 +793,9 @@ private:
*
* If bOnlyBuffers is specified, it only cleans up the buffers. */
void StartStreamCleanup(bool bOnlyBuffers = false);
std::mutex mPostRecordingActionMutex;
PostRecordingAction mPostRecordingAction;
};
static constexpr unsigned ScrubPollInterval_ms = 50;

View File

@ -10,6 +10,7 @@
#include "UpdateManager.h"
#include "UpdatePopupDialog.h"
#include "AudioIO.h"
#include "NetworkManager.h"
#include "IResponse.h"
#include "Request.h"
@ -71,9 +72,10 @@ void UpdateManager::GetUpdates()
response->setRequestFinishedCallback([response, this](audacity::network_manager::IResponse*) {
auto gAudioIO = AudioIO::Get();
if (response->getError() != audacity::network_manager::NetworkError::NoError)
{
wxTheApp->CallAfter([] {ShowExceptionDialog(nullptr,
gAudioIO->CallAfterRecording([] {ShowExceptionDialog(nullptr,
XC("Error checking for update", "update dialog"),
XC("Unable to connect to Audacity update server.", "update dialog"),
wxString());
@ -84,7 +86,7 @@ void UpdateManager::GetUpdates()
if (!mUpdateDataParser.Parse(response->readAll<VersionPatch::UpdateDataFormat>(), &mVersionPatch))
{
wxTheApp->CallAfter([] {ShowExceptionDialog(nullptr,
gAudioIO->CallAfterRecording([] {ShowExceptionDialog(nullptr,
XC("Error checking for update", "update dialog"),
XC("Update data was corrupted.", "update dialog"),
wxString());
@ -95,7 +97,7 @@ void UpdateManager::GetUpdates()
if (mVersionPatch.version > CurrentBuildVersion())
{
wxTheApp->CallAfter([this] {
gAudioIO->CallAfterRecording([this] {
UpdatePopupDialog dlg(nullptr, mVersionPatch);
const int code = dlg.ShowModal();