Merge pull request #10611 from liamwhite/audio-deadlock
audio_renderer: resolve adsp thread deadlock shutdown
This commit is contained in:
		| @@ -105,7 +105,7 @@ void AudioRenderer::Start(AudioRenderer_Mailbox* mailbox_) { | ||||
|     } | ||||
|  | ||||
|     mailbox = mailbox_; | ||||
|     thread = std::thread(&AudioRenderer::ThreadFunc, this); | ||||
|     thread = std::jthread([this](std::stop_token stop_token) { ThreadFunc(stop_token); }); | ||||
|     running = true; | ||||
| } | ||||
|  | ||||
| @@ -131,7 +131,7 @@ void AudioRenderer::CreateSinkStreams() { | ||||
|     } | ||||
| } | ||||
|  | ||||
| void AudioRenderer::ThreadFunc() { | ||||
| void AudioRenderer::ThreadFunc(std::stop_token stop_token) { | ||||
|     static constexpr char name[]{"AudioRenderer"}; | ||||
|     MicroProfileOnThreadCreate(name); | ||||
|     Common::SetCurrentThreadName(name); | ||||
| @@ -146,7 +146,7 @@ void AudioRenderer::ThreadFunc() { | ||||
|  | ||||
|     constexpr u64 max_process_time{2'304'000ULL}; | ||||
|  | ||||
|     while (true) { | ||||
|     while (!stop_token.stop_requested()) { | ||||
|         auto message{mailbox->ADSPWaitMessage()}; | ||||
|         switch (message) { | ||||
|         case RenderMessage::AudioRenderer_Shutdown: | ||||
| @@ -194,7 +194,7 @@ void AudioRenderer::ThreadFunc() { | ||||
|                     max_time = std::min(command_buffer.time_limit, max_time); | ||||
|                     command_list_processor.SetProcessTimeMax(max_time); | ||||
|  | ||||
|                     streams[index]->WaitFreeSpace(); | ||||
|                     streams[index]->WaitFreeSpace(stop_token); | ||||
|  | ||||
|                     // Process the command list | ||||
|                     { | ||||
|   | ||||
| @@ -177,7 +177,7 @@ private: | ||||
|     /** | ||||
|      * Main AudioRenderer thread, responsible for processing the command lists. | ||||
|      */ | ||||
|     void ThreadFunc(); | ||||
|     void ThreadFunc(std::stop_token stop_token); | ||||
|  | ||||
|     /** | ||||
|      * Creates the streams which will receive the processed samples. | ||||
| @@ -187,7 +187,7 @@ private: | ||||
|     /// Core system | ||||
|     Core::System& system; | ||||
|     /// Main thread | ||||
|     std::thread thread{}; | ||||
|     std::jthread thread{}; | ||||
|     /// The current state | ||||
|     std::atomic<bool> running{}; | ||||
|     /// The active mailbox | ||||
|   | ||||
| @@ -269,12 +269,13 @@ u64 SinkStream::GetExpectedPlayedSampleCount() { | ||||
|     return std::min<u64>(exp_played_sample_count, max_played_sample_count) + TargetSampleCount * 3; | ||||
| } | ||||
|  | ||||
| void SinkStream::WaitFreeSpace() { | ||||
| void SinkStream::WaitFreeSpace(std::stop_token stop_token) { | ||||
|     std::unique_lock lk{release_mutex}; | ||||
|     release_cv.wait_for(lk, std::chrono::milliseconds(5), | ||||
|                         [this]() { return queued_buffers < max_queue_size; }); | ||||
|     if (queued_buffers > max_queue_size + 3) { | ||||
|         release_cv.wait(lk, [this]() { return queued_buffers < max_queue_size; }); | ||||
|         Common::CondvarWait(release_cv, lk, stop_token, | ||||
|                             [this] { return queued_buffers < max_queue_size; }); | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -13,6 +13,7 @@ | ||||
|  | ||||
| #include "audio_core/common/common.h" | ||||
| #include "common/common_types.h" | ||||
| #include "common/polyfill_thread.h" | ||||
| #include "common/reader_writer_queue.h" | ||||
| #include "common/ring_buffer.h" | ||||
| #include "common/thread.h" | ||||
| @@ -210,7 +211,7 @@ public: | ||||
|     /** | ||||
|      * Waits for free space in the sample ring buffer | ||||
|      */ | ||||
|     void WaitFreeSpace(); | ||||
|     void WaitFreeSpace(std::stop_token stop_token); | ||||
|  | ||||
| protected: | ||||
|     /// Core system | ||||
| @@ -252,7 +253,7 @@ private: | ||||
|     /// Set via IAudioDevice service calls | ||||
|     f32 device_volume{1.0f}; | ||||
|     /// Signalled when ring buffer entries are consumed | ||||
|     std::condition_variable release_cv; | ||||
|     std::condition_variable_any release_cv; | ||||
|     std::mutex release_mutex; | ||||
| }; | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user