From ab1ec8e46423f4814999a88b9f29f0592c13552d Mon Sep 17 00:00:00 2001 From: Glenn Maynard Date: Fri, 13 Dec 2002 06:18:09 +0000 Subject: [PATCH] Add some lock handling stuff for the sound code. --- stepmania/src/RageThreads.cpp | 79 +++++++++++++++++++++++++++++++++++ stepmania/src/RageThreads.h | 36 ++++++++++++++++ 2 files changed, 115 insertions(+) create mode 100644 stepmania/src/RageThreads.cpp create mode 100644 stepmania/src/RageThreads.h diff --git a/stepmania/src/RageThreads.cpp b/stepmania/src/RageThreads.cpp new file mode 100644 index 0000000000..c98e3760a9 --- /dev/null +++ b/stepmania/src/RageThreads.cpp @@ -0,0 +1,79 @@ +/* + * If you're going to use threads, remember this: + * + * Threads suck. + * + * If there's any way to avoid them, take it! Threaded code an order of + * magnitude more complicated, harder to debug and harder to make robust. + * + * That said, here are a few helpers for when they're unavoidable. (Use + * SDL for the rest.) + */ + +#include "stdafx.h" + +#include "RageThreads.h" + +RageMutex::RageMutex() +{ + Locked = 0; + mut = SDL_CreateMutex(); + mutwait = SDL_CreateMutex(); +} + +RageMutex::~RageMutex() +{ + SDL_DestroyMutex(mut); + SDL_DestroyMutex(mutwait); +} + +void RageMutex::Lock() +{ + while(1) + { + SDL_LockMutex(mut); + if(!Locked || LockedBy == SDL_ThreadID()) + { + if(!Locked) + { + /* This mutex is now locked. */ + SDL_LockMutex(mutwait); + LockedBy = SDL_ThreadID(); + } /* (else it was already locked and we're just increasing the counter) */ + Locked++; + SDL_UnlockMutex(mut); + return; + } + + SDL_UnlockMutex(mut); + + /* Someone else is locking it. Wait until it's available and try again. */ + SDL_LockMutex(mutwait); + SDL_UnlockMutex(mutwait); + } +} + +void RageMutex::Unlock() +{ + SDL_LockMutex(mut); + ASSERT(Locked); + ASSERT(LockedBy == SDL_ThreadID()); + + Locked--; + if(!Locked) + { + LockedBy = 0; + SDL_UnlockMutex(mutwait); + } + + SDL_UnlockMutex(mut); +} + +/* +----------------------------------------------------------------------------- + File: RageThreads + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. + Glenn Maynard +----------------------------------------------------------------------------- +*/ diff --git a/stepmania/src/RageThreads.h b/stepmania/src/RageThreads.h new file mode 100644 index 0000000000..3f3fd42232 --- /dev/null +++ b/stepmania/src/RageThreads.h @@ -0,0 +1,36 @@ +#ifndef RAGE_THREADS_H +#define RAGE_THREADS_H + +#include "SDL_Thread.h" + +/* Mutex class that follows the behavior of Windows mutexes: if the same + * thread locks the same mutex twice, we just increase a refcount; a mutex + * is considered unlocked when the refcount reaches zero. This is more + * convenient, though much slower on some archs. (We don't have any tightly- + * coupled threads, so that's OK.) */ +class RageMutex +{ + Uint32 LockedBy; + int Locked; + SDL_mutex *mut, *mutwait; + +public: + void Lock(); + void Unlock(); + RageMutex(); + ~RageMutex(); +}; + +/* Lock a mutex on construction, unlock it on destruction. Helps for functions + * with more than one return path. */ +class LockMutex +{ + RageMutex &mutex; + +public: + LockMutex(RageMutex &mut): mutex(mut) { mutex.Lock(); } + ~LockMutex() { mutex.Unlock(); } + LockMutex(LockMutex &cpy): mutex(cpy.mutex) { mutex.Lock(); } +}; + +#endif