#include "../../SDL_internal.h"
#include "SDL_thread.h"
#include "SDL_systhread_c.h"
struct SDL_mutex
{
int recursive;
SDL_threadID owner;
SDL_sem *sem;
};
SDL_mutex *
SDL_CreateMutex(void)
{
SDL_mutex *mutex;
mutex = (SDL_mutex *) SDL_calloc(1, sizeof(*mutex));
#if !SDL_THREADS_DISABLED
if (mutex) {
mutex->sem = SDL_CreateSemaphore(1);
mutex->recursive = 0;
mutex->owner = 0;
if (!mutex->sem) {
SDL_free(mutex);
mutex = NULL;
}
} else {
SDL_OutOfMemory();
}
#endif
return mutex;
}
void
SDL_DestroyMutex(SDL_mutex * mutex)
{
if (mutex) {
if (mutex->sem) {
SDL_DestroySemaphore(mutex->sem);
}
SDL_free(mutex);
}
}
int
SDL_LockMutex(SDL_mutex * mutex)
{
#if SDL_THREADS_DISABLED
return 0;
#else
SDL_threadID this_thread;
if (mutex == NULL) {
return SDL_InvalidParamError("mutex");
}
this_thread = SDL_ThreadID();
if (mutex->owner == this_thread) {
++mutex->recursive;
} else {
SDL_SemWait(mutex->sem);
mutex->owner = this_thread;
mutex->recursive = 0;
}
return 0;
#endif
}
int
SDL_TryLockMutex(SDL_mutex * mutex)
{
#if SDL_THREADS_DISABLED
return 0;
#else
int retval = 0;
SDL_threadID this_thread;
if (mutex == NULL) {
return SDL_InvalidParamError("mutex");
}
this_thread = SDL_ThreadID();
if (mutex->owner == this_thread) {
++mutex->recursive;
} else {
retval = SDL_SemWait(mutex->sem);
if (retval == 0) {
mutex->owner = this_thread;
mutex->recursive = 0;
}
}
return retval;
#endif
}
int
SDL_mutexV(SDL_mutex * mutex)
{
#if SDL_THREADS_DISABLED
return 0;
#else
if (mutex == NULL) {
return SDL_InvalidParamError("mutex");
}
if (SDL_ThreadID() != mutex->owner) {
return SDL_SetError("mutex not owned by this thread");
}
if (mutex->recursive) {
--mutex->recursive;
} else {
mutex->owner = 0;
SDL_SemPost(mutex->sem);
}
return 0;
#endif
}