From 16922a9519a5ea07c3229868956df4b82e93bad0 Mon Sep 17 00:00:00 2001 From: SirLynix Date: Tue, 7 Jun 2022 20:18:26 +0200 Subject: [PATCH] Audio/Music: Fix datarace --- include/Nazara/Audio/Music.hpp | 2 +- src/Nazara/Audio/Music.cpp | 14 ++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/include/Nazara/Audio/Music.hpp b/include/Nazara/Audio/Music.hpp index 72738e83a..38b4ef733 100644 --- a/include/Nazara/Audio/Music.hpp +++ b/include/Nazara/Audio/Music.hpp @@ -63,7 +63,7 @@ namespace Nz AudioFormat m_audioFormat; std::atomic_bool m_streaming; std::atomic m_processedSamples; - mutable std::mutex m_bufferLock; + mutable std::recursive_mutex m_sourceLock; std::size_t m_bufferCount; std::shared_ptr m_stream; std::thread m_thread; diff --git a/src/Nazara/Audio/Music.cpp b/src/Nazara/Audio/Music.cpp index 7bda5a05f..fc6e0b46e 100644 --- a/src/Nazara/Audio/Music.cpp +++ b/src/Nazara/Audio/Music.cpp @@ -90,7 +90,7 @@ namespace Nz */ void Music::EnableLooping(bool loop) { - std::lock_guard lock(m_bufferLock); + std::lock_guard lock(m_sourceLock); m_looping = loop; } @@ -135,7 +135,7 @@ namespace Nz return 0; // Prevent music thread from enqueuing new buffers while we're getting the count - std::lock_guard lock(m_bufferLock); + std::lock_guard lock(m_sourceLock); UInt32 sampleOffset = m_source->GetSampleOffset(); UInt32 playingOffset = SafeCast((1000ULL * (sampleOffset + (m_processedSamples / GetChannelCount(m_stream->GetFormat())))) / m_sampleRate); @@ -187,7 +187,7 @@ namespace Nz { NazaraAssert(m_stream, "Music not created"); - std::lock_guard lock(m_bufferLock); + std::lock_guard lock(m_sourceLock); SoundStatus status = m_source->GetStatus(); @@ -206,7 +206,7 @@ namespace Nz */ bool Music::IsLooping() const { - std::lock_guard lock(m_bufferLock); + std::lock_guard lock(m_sourceLock); return m_looping; } @@ -268,7 +268,7 @@ namespace Nz */ void Music::Pause() { - std::lock_guard lock(m_bufferLock); + std::lock_guard lock(m_sourceLock); m_source->Pause(); } @@ -290,6 +290,8 @@ namespace Nz // Maybe we are already playing if (m_streaming) { + std::lock_guard lock(m_sourceLock); + switch (GetStatus()) { case SoundStatus::Playing: @@ -446,7 +448,7 @@ namespace Nz // Wait until buffers are processed std::this_thread::sleep_for(std::chrono::milliseconds(50)); - std::lock_guard lock(m_bufferLock); + std::lock_guard lock(m_sourceLock); SoundStatus status = m_source->GetStatus(); if (status == SoundStatus::Stopped)