#include "SDL_internal.h"
#include "SDL_systhread_c.h"
struct SDL_Mutex
{
int recursive;
SDL_ThreadID owner;
SDL_Semaphore *sem;
};
SDL_Mutex *SDL_CreateMutex(void)
{
SDL_Mutex *mutex = (SDL_Mutex *)SDL_calloc(1, sizeof(*mutex));
#ifndef SDL_THREADS_DISABLED
if (mutex) {
mutex->sem = SDL_CreateSemaphore(1);
mutex->recursive = 0;
mutex->owner = 0;
if (!mutex->sem) {
SDL_free(mutex);
mutex = NULL;
}
}
#endif
return mutex;
}
void SDL_DestroyMutex(SDL_Mutex *mutex)
{
if (mutex) {
if (mutex->sem) {
SDL_DestroySemaphore(mutex->sem);
}
SDL_free(mutex);
}
}
void SDL_LockMutex(SDL_Mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS {
#ifndef SDL_THREADS_DISABLED
if (mutex != NULL) {
SDL_ThreadID this_thread = SDL_GetCurrentThreadID();
if (mutex->owner == this_thread) {
++mutex->recursive;
} else {
SDL_WaitSemaphore(mutex->sem);
mutex->owner = this_thread;
mutex->recursive = 0;
}
}
#endif }
bool SDL_TryLockMutex(SDL_Mutex *mutex)
{
bool result = true;
#ifndef SDL_THREADS_DISABLED
if (mutex) {
SDL_ThreadID this_thread = SDL_GetCurrentThreadID();
if (mutex->owner == this_thread) {
++mutex->recursive;
} else {
result = SDL_TryWaitSemaphore(mutex->sem);
if (result) {
mutex->owner = this_thread;
mutex->recursive = 0;
}
}
}
#endif return result;
}
void SDL_UnlockMutex(SDL_Mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS {
#ifndef SDL_THREADS_DISABLED
if (mutex != NULL) {
if (SDL_GetCurrentThreadID() != mutex->owner) {
SDL_assert(!"Tried to unlock a mutex we don't own!");
return; }
if (mutex->recursive) {
--mutex->recursive;
} else {
mutex->owner = 0;
SDL_SignalSemaphore(mutex->sem);
}
}
#endif }