Add some lock handling stuff for the sound code.
This commit is contained in:
@@ -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
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
@@ -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
|
||||||
Reference in New Issue
Block a user