From f1f80c0a399b2a895821423081a6d624d2424113 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Sun, 23 Feb 2020 02:20:39 +1100 Subject: [PATCH] audiomanager: fixed segfault if olive is closed while the devices are getting refreshed --- app/audio/audiomanager.cpp | 31 +++++++++++++++++++------------ app/audio/audiomanager.h | 4 +++- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/app/audio/audiomanager.cpp b/app/audio/audiomanager.cpp index 3ce9abd8a..df4ca479e 100644 --- a/app/audio/audiomanager.cpp +++ b/app/audio/audiomanager.cpp @@ -46,24 +46,22 @@ AudioManager *AudioManager::instance() void AudioManager::RefreshDevices() { - if (refreshing_devices_) { + if (refresh_thread_) { return; } input_devices_.clear(); output_devices_.clear(); - refreshing_devices_ = true; - // Refreshing devices can take some time, so we do it in a separate thread - QThread* thread = new QThread(); - connect(thread, &QThread::finished, thread, &QThread::deleteLater); + refresh_thread_ = new QThread(this); + connect(refresh_thread_, &QThread::finished, refresh_thread_, &QThread::deleteLater); - thread->start(QThread::IdlePriority); + refresh_thread_->start(QThread::IdlePriority); AudioRefreshDevicesObject* refresher = new AudioRefreshDevicesObject(); - connect(refresher, &AudioRefreshDevicesObject::ListsReady, this, &AudioManager::RefreshThreadDone); - refresher->moveToThread(thread); + connect(refresher, &AudioRefreshDevicesObject::ListsReady, this, &AudioManager::RefreshThreadDone, Qt::QueuedConnection); + refresher->moveToThread(refresh_thread_); QMetaObject::invokeMethod(refresher, "Refresh", @@ -72,7 +70,7 @@ void AudioManager::RefreshDevices() bool AudioManager::IsRefreshing() { - return refreshing_devices_; + return refresh_thread_; } void AudioManager::PushToOutput(const QByteArray &samples) @@ -191,7 +189,7 @@ void AudioManager::ReverseBuffer(char *buffer, int buffer_size, int sample_size) AudioManager::AudioManager() : input_(nullptr), input_file_(nullptr), - refreshing_devices_(false) + refresh_thread_(nullptr) { RefreshDevices(); @@ -200,6 +198,14 @@ AudioManager::AudioManager() : output_manager_.SetEnableSendingSamples(true); } +AudioManager::~AudioManager() +{ + if (refresh_thread_) { + refresh_thread_->quit(); + refresh_thread_->wait(); + } +} + void AudioManager::RefreshThreadDone() { AudioRefreshDevicesObject* refresher = static_cast(sender()); @@ -207,7 +213,7 @@ void AudioManager::RefreshThreadDone() output_devices_ = refresher->output_devices(); input_devices_ = refresher->input_devices(); - refreshing_devices_ = false; + QString preferred_audio_output = Config::Current()["PreferredAudioOutput"].toString(); @@ -242,7 +248,8 @@ void AudioManager::RefreshThreadDone() } // Clean up refresher object - refresher->thread()->quit(); + refresh_thread_->quit(); + refresh_thread_ = nullptr; refresher->deleteLater(); emit DeviceListReady(); diff --git a/app/audio/audiomanager.h b/app/audio/audiomanager.h index ee3de09eb..8a806652e 100644 --- a/app/audio/audiomanager.h +++ b/app/audio/audiomanager.h @@ -105,6 +105,8 @@ signals: private: AudioManager(); + virtual ~AudioManager() override; + QList input_devices_; QList output_devices_; @@ -120,7 +122,7 @@ private: QAudioDeviceInfo input_device_info_; QIODevice* input_file_; - bool refreshing_devices_; + QThread* refresh_thread_; private slots: void RefreshThreadDone();