From c79ec673f410446e6d815bb04136476ef05c8d7a Mon Sep 17 00:00:00 2001 From: Gleb Mazovetskiy Date: Mon, 17 May 2021 06:16:33 +0100 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Implement=20std's=20Lockab?= =?UTF-8?q?le=20for=20SDL=20mutex=20wrapper?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rather than rolling our own lock guard, implement the requirements for using `std::lock_guard` et al and use that. --- Source/sound.cpp | 13 +++++---- Source/storm/storm.cpp | 9 +++--- Source/utils/push_aulib_decoder.cpp | 9 +++--- Source/utils/push_aulib_decoder.h | 3 +- Source/utils/sdl_mutex.h | 43 +++++++++++++++++------------ 5 files changed, 44 insertions(+), 33 deletions(-) diff --git a/Source/sound.cpp b/Source/sound.cpp index 8ac823218..48f37dc90 100644 --- a/Source/sound.cpp +++ b/Source/sound.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -69,7 +70,7 @@ void CleanupMusic() } std::list> duplicateSounds; -SDLMutexUniquePtr duplicateSoundsMutex; +std::optional duplicateSoundsMutex; SoundSample *DuplicateSound(const SoundSample &sound) { @@ -79,13 +80,13 @@ SoundSample *DuplicateSound(const SoundSample &sound) auto *result = duplicate.get(); decltype(duplicateSounds.begin()) it; { - SDLMutexLockGuard lock(duplicateSoundsMutex.get()); + const std::lock_guard lock(*duplicateSoundsMutex); duplicateSounds.push_back(std::move(duplicate)); it = duplicateSounds.end(); --it; } result->SetFinishCallback([it]([[maybe_unused]] Aulib::Stream &stream) { - SDLMutexLockGuard lock(duplicateSoundsMutex.get()); + const std::lock_guard lock(*duplicateSoundsMutex); duplicateSounds.erase(it); }); return result; @@ -129,7 +130,7 @@ static int CapVolume(int volume) void ClearDuplicateSounds() { - SDLMutexLockGuard lock(duplicateSoundsMutex.get()); + const std::lock_guard lock(*duplicateSoundsMutex); duplicateSounds.clear(); } @@ -214,7 +215,7 @@ void snd_init() LogVerbose(LogCategory::Audio, "Aulib sampleRate={} channels={} frameSize={} format={:#x}", Aulib::sampleRate(), Aulib::channelCount(), Aulib::frameSize(), Aulib::sampleFormat()); - duplicateSoundsMutex = SDLMutexUniquePtr { SDL_CreateMutex() }; + duplicateSoundsMutex.emplace(); gbSndInited = true; } @@ -222,7 +223,7 @@ void snd_deinit() { if (gbSndInited) { Aulib::quit(); - duplicateSoundsMutex = nullptr; + duplicateSoundsMutex = std::nullopt; } gbSndInited = false; diff --git a/Source/storm/storm.cpp b/Source/storm/storm.cpp index 1b3fd34ab..7964e49c5 100644 --- a/Source/storm/storm.cpp +++ b/Source/storm/storm.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include "Radon.hpp" @@ -34,19 +35,19 @@ namespace { bool directFileAccess = false; std::string *SBasePath = nullptr; -} // namespace +SdlMutex Mutex; -SDL_mutex *Mutex = SDL_CreateMutex(); +} // namespace bool SFileReadFileThreadSafe(HANDLE hFile, void *buffer, DWORD nNumberOfBytesToRead, DWORD *read, int *lpDistanceToMoveHigh) { - SDLMutexLockGuard lock(Mutex); + const std::lock_guard lock(Mutex); return SFileReadFile(hFile, buffer, nNumberOfBytesToRead, read, lpDistanceToMoveHigh); } bool SFileCloseFileThreadSafe(HANDLE hFile) { - SDLMutexLockGuard lock(Mutex); + const std::lock_guard lock(Mutex); return SFileCloseFile(hFile); } diff --git a/Source/utils/push_aulib_decoder.cpp b/Source/utils/push_aulib_decoder.cpp index 93330bb75..fa3cf0e20 100644 --- a/Source/utils/push_aulib_decoder.cpp +++ b/Source/utils/push_aulib_decoder.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include @@ -17,7 +18,7 @@ void PushAulibDecoder::PushSamples(const std::int16_t *data, unsigned size) noex std::memcpy(item.data.get(), data, size * sizeof(data[0])); item.len = size; item.pos = item.data.get(); - SDLMutexLockGuard lock(queue_mutex_.get()); + const std::lock_guard lock(queue_mutex_); queue_.push(std::move(item)); } @@ -31,13 +32,13 @@ void PushAulibDecoder::PushSamples(const std::uint8_t *data, unsigned size) noex item.data[i] = static_cast((data[i] - Center) * Scale); item.len = size; item.pos = item.data.get(); - SDLMutexLockGuard lock(queue_mutex_.get()); + const std::lock_guard lock(queue_mutex_); queue_.push(std::move(item)); } void PushAulibDecoder::DiscardPendingSamples() noexcept { - SDLMutexLockGuard lock(queue_mutex_.get()); + const std::lock_guard lock(queue_mutex_); queue_ = std::queue(); } @@ -75,7 +76,7 @@ int PushAulibDecoder::doDecoding(float buf[], int len, bool &callAgain) unsigned remaining = len; { - SDLMutexLockGuard lock(queue_mutex_.get()); + const std::lock_guard lock(queue_mutex_); AudioQueueItem *item; while ((item = Next()) != nullptr) { if (static_cast(remaining) <= item->len) { diff --git a/Source/utils/push_aulib_decoder.h b/Source/utils/push_aulib_decoder.h index 250b465a7..8943dd812 100644 --- a/Source/utils/push_aulib_decoder.h +++ b/Source/utils/push_aulib_decoder.h @@ -20,7 +20,6 @@ public: PushAulibDecoder(int numChannels, int sampleRate) : numChannels_(numChannels) , sampleRate_(sampleRate) - , queue_mutex_(SDL_CreateMutex()) { } @@ -61,7 +60,7 @@ private: AudioQueueItem *Next(); std::queue queue_; - SDLMutexUniquePtr queue_mutex_; + SdlMutex queue_mutex_; }; } // namespace devilution diff --git a/Source/utils/sdl_mutex.h b/Source/utils/sdl_mutex.h index e55febea7..3e99250bf 100644 --- a/Source/utils/sdl_mutex.h +++ b/Source/utils/sdl_mutex.h @@ -3,38 +3,47 @@ #include #include +#include namespace devilution { -/** - * @brief Deletes the SDL mutex using `SDL_DestroyMutex`. +/* + * RAII wrapper for SDL_mutex. Satisfies std's "Lockable" (SDL 2) or "BasicLockable" (SDL 1) + * requirements so it can be used with std::lock_guard and friends. */ -struct SDLMutexDeleter { - void operator()(SDL_mutex *mutex) const +class SdlMutex final { +public: + SdlMutex() + : mutex_(SDL_CreateMutex()) { - SDL_DestroyMutex(mutex); } -}; -using SDLMutexUniquePtr = std::unique_ptr; + ~SdlMutex() + { + SDL_DestroyMutex(mutex_); + } -struct SDLMutexLockGuard { -public: - explicit SDLMutexLockGuard(SDL_mutex *mutex) - : mutex_(mutex) + SdlMutex(const SdlMutex &) = delete; + SdlMutex(SdlMutex &&) = delete; + SdlMutex &operator=(const SdlMutex &) = delete; + SdlMutex &operator=(SdlMutex &&) = delete; + + void lock() noexcept // NOLINT(readability-identifier-naming) { SDL_LockMutex(mutex_); } - ~SDLMutexLockGuard() +#if SDL_VERSION_ATLEAST(2, 0, 0) + bool try_lock() noexcept // NOLINT(readability-identifier-naming) { - SDL_UnlockMutex(mutex_); + return SDL_TryLockMutex(mutex_) == 0; } +#endif - SDLMutexLockGuard(const SDLMutexLockGuard &) = delete; - SDLMutexLockGuard(SDLMutexLockGuard &&) = delete; - SDLMutexLockGuard &operator=(const SDLMutexLockGuard &) = delete; - SDLMutexLockGuard &operator=(SDLMutexLockGuard &&) = delete; + void unlock() noexcept // NOLINT(readability-identifier-naming) + { + SDL_UnlockMutex(mutex_); + } private: SDL_mutex *mutex_;