Add SDL_TryLockMutex and implementations for all platforms

This commit is contained in:
Edward Rudd 2013-03-05 18:54:55 -05:00
parent 191718be44
commit ac51aff110
5 changed files with 140 additions and 2 deletions

View file

@ -73,6 +73,13 @@ extern DECLSPEC SDL_mutex *SDLCALL SDL_CreateMutex(void);
#define SDL_LockMutex(m) SDL_mutexP(m) #define SDL_LockMutex(m) SDL_mutexP(m)
extern DECLSPEC int SDLCALL SDL_mutexP(SDL_mutex * mutex); 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. * Unlock the mutex.
* *

View file

@ -68,7 +68,7 @@ SDL_DestroyMutex(SDL_mutex * mutex)
} }
} }
/* Lock the semaphore */ /* Lock the mutex */
int int
SDL_mutexP(SDL_mutex * mutex) SDL_mutexP(SDL_mutex * mutex)
{ {
@ -99,6 +99,40 @@ SDL_mutexP(SDL_mutex * mutex)
#endif /* SDL_THREADS_DISABLED */ #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 */ /* Unlock the mutex */
int int
SDL_mutexV(SDL_mutex * mutex) SDL_mutexV(SDL_mutex * mutex)

View file

@ -76,7 +76,7 @@ SDL_DestroyMutex(SDL_mutex * mutex)
} }
} }
/* Lock the semaphore */ /* Lock the mutex */
int int
SDL_mutexP(SDL_mutex * mutex) SDL_mutexP(SDL_mutex * mutex)
{ {
@ -107,6 +107,40 @@ SDL_mutexP(SDL_mutex * mutex)
#endif /* DISABLE_THREADS */ #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 */ /* Unlock the mutex */
int int
SDL_mutexV(SDL_mutex * mutex) SDL_mutexV(SDL_mutex * mutex)

View file

@ -22,6 +22,7 @@
#define _GNU_SOURCE #define _GNU_SOURCE
#include <pthread.h> #include <pthread.h>
#include <errno.h>
#include "SDL_thread.h" #include "SDL_thread.h"
@ -117,6 +118,52 @@ SDL_mutexP(SDL_mutex * mutex)
return retval; return retval;
} }
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 int
SDL_mutexV(SDL_mutex * mutex) SDL_mutexV(SDL_mutex * mutex)
{ {

View file

@ -75,6 +75,22 @@ SDL_mutexP(SDL_mutex * mutex)
return (0); 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 */ /* Unlock the mutex */
int int
SDL_mutexV(SDL_mutex * mutex) SDL_mutexV(SDL_mutex * mutex)