tree 2d0291d55429 parent ddf4df4dfdd6 author Edward Rudd 1357073701 18000 committer Edward Rudd 1357073701 18000 revision 6804 branch default Add SDL_TryLockMutex and implementations for all platforms diff --git a/include/SDL_mutex.h b/include/SDL_mutex.h --- a/include/SDL_mutex.h +++ b/include/SDL_mutex.h @@ -74,6 +74,13 @@ extern DECLSPEC int SDLCALL SDL_mutexP(SDL_mutex * mutex); /** + * Try to lock the mutex + * + * \return 0, SDL_MUTEX_TIMEDOUT, or -1 on error + */ +extern DECLSPEC int SDLCALL SDL_TryLockMutex(SDL_mutex * mutex); + +/** * Unlock the mutex. * * \return 0, or -1 on error. diff --git a/src/thread/generic/SDL_sysmutex.c b/src/thread/generic/SDL_sysmutex.c --- a/src/thread/generic/SDL_sysmutex.c +++ b/src/thread/generic/SDL_sysmutex.c @@ -68,7 +68,7 @@ } } -/* Lock the semaphore */ +/* Lock the mutex */ int SDL_mutexP(SDL_mutex * mutex) { @@ -99,6 +99,40 @@ #endif /* SDL_THREADS_DISABLED */ } +/* try Lock the mutex */ +int +SDL_TryLockMutex(SDL_mutex * mutex) +{ +#if SDL_THREADS_DISABLED + return 0; +#else + int retval = 0; + SDL_threadID this_thread; + + if (mutex == NULL) { + SDL_SetError("Passed a NULL mutex"); + return -1; + } + + this_thread = SDL_ThreadID(); + if (mutex->owner == this_thread) { + ++mutex->recursive; + } else { + /* The order of operations is important. + We set the locking thread id after we obtain the lock + so unlocks from other threads will fail. + */ + retval = SDL_SemWait(mutex->sem); + if (retval == 0) { + mutex->owner = this_thread; + mutex->recursive = 0; + } + } + + return retval; +#endif /* SDL_THREADS_DISABLED */ +} + /* Unlock the mutex */ int SDL_mutexV(SDL_mutex * mutex) diff --git a/src/thread/nds/SDL_sysmutex.c b/src/thread/nds/SDL_sysmutex.c --- a/src/thread/nds/SDL_sysmutex.c +++ b/src/thread/nds/SDL_sysmutex.c @@ -76,7 +76,7 @@ } } -/* Lock the semaphore */ +/* Lock the mutex */ int SDL_mutexP(SDL_mutex * mutex) { @@ -107,6 +107,40 @@ #endif /* DISABLE_THREADS */ } +/* Try Lock the mutex */ +int +SDL_TryLockMutex(SDL_mutex * mutex) +{ +#ifdef DISABLE_THREADS + return 0; +#else + int retval = 0; + SDL_threadID this_thread; + + if (mutex == NULL) { + SDL_SetError("Passed a NULL mutex"); + return -1; + } + + this_thread = SDL_ThreadID(); + if (mutex->owner == this_thread) { + ++mutex->recursive; + } else { + /* The order of operations is important. + We set the locking thread id after we obtain the lock + so unlocks from other threads will fail. + */ + retval = SDL_SemTryWait(mutex->sem); + if (ret == 0) { + mutex->owner = this_thread; + mutex->recursive = 0; + } + } + + return retval; +#endif /* DISABLE_THREADS */ +} + /* Unlock the mutex */ int SDL_mutexV(SDL_mutex * mutex) diff --git a/src/thread/pthread/SDL_sysmutex.c b/src/thread/pthread/SDL_sysmutex.c --- a/src/thread/pthread/SDL_sysmutex.c +++ b/src/thread/pthread/SDL_sysmutex.c @@ -22,6 +22,7 @@ #define _GNU_SOURCE #include +#include #include "SDL_thread.h" @@ -118,6 +119,52 @@ } int +SDL_TryLockMutex(SDL_mutex * mutex) +{ + int retval; +#if FAKE_RECURSIVE_MUTEX + pthread_t this_thread; +#endif + + if (mutex == NULL) { + SDL_SetError("Passed a NULL mutex"); + return -1; + } + + retval = 0; +#if FAKE_RECURSIVE_MUTEX + this_thread = pthread_self(); + if (mutex->owner == this_thead) { + ++mutex->recursive; + } else { + /* The order of operations is important. + We set the locking thread id after we obtain the lock + so unlocks from other threads will fail. + */ + if (pthread_mutex_lock(&mutex->id) == 0) { + mutex->owner = this_thread; + mutex->recursive = 0; + } else if (errno == EBUSY) { + retval = SDL_MUTEX_TIMEDOUT; + } else { + SDL_SetError("pthread_mutex_trylock() failed"); + retval = -1; + } + } +#else + if (pthread_mutex_trylock(&mutex->id) != 0) { + if (errno == EBUSY) { + retval = SDL_MUTEX_TIMEDOUT; + } else { + SDL_SetError("pthread_mutex_trylock() failed"); + retval = -1; + } + } +#endif + return retval; +} + +int SDL_mutexV(SDL_mutex * mutex) { int retval; diff --git a/src/thread/windows/SDL_sysmutex.c b/src/thread/windows/SDL_sysmutex.c --- a/src/thread/windows/SDL_sysmutex.c +++ b/src/thread/windows/SDL_sysmutex.c @@ -75,6 +75,22 @@ return (0); } +/* TryLock the mutex */ +int +SDL_TryLockMutex(SDL_mutex * mutex) +{ + if (mutex == NULL) { + SDL_SetError("Passed a NULL mutex"); + return -1; + } + + int retval = 0; + if (TryEnterCriticalSection(&mutex->cs) == 0) { + retval = SDL_MUTEX_TIMEDOUT; + } + return retval; +} + /* Unlock the mutex */ int SDL_mutexV(SDL_mutex * mutex)