Add SDL_TryLockMutex and implementations for all platforms
authorEdward Rudd <urkle@outoforder.cc>
Tue, 05 Mar 2013 18:54:55 -0500
changeset 6966 090df160f6e0
parent 6965 ab4bb4e99961
child 6967 adc80d085ddf
Add SDL_TryLockMutex and implementations for all platforms
include/SDL_mutex.h
src/thread/generic/SDL_sysmutex.c
src/thread/nds/SDL_sysmutex.c
src/thread/pthread/SDL_sysmutex.c
src/thread/windows/SDL_sysmutex.c
--- a/include/SDL_mutex.h	Tue Mar 05 18:01:59 2013 -0500
+++ b/include/SDL_mutex.h	Tue Mar 05 18:54:55 2013 -0500
@@ -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.
--- a/src/thread/generic/SDL_sysmutex.c	Tue Mar 05 18:01:59 2013 -0500
+++ b/src/thread/generic/SDL_sysmutex.c	Tue Mar 05 18:54:55 2013 -0500
@@ -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)
--- a/src/thread/nds/SDL_sysmutex.c	Tue Mar 05 18:01:59 2013 -0500
+++ b/src/thread/nds/SDL_sysmutex.c	Tue Mar 05 18:54:55 2013 -0500
@@ -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)
--- a/src/thread/pthread/SDL_sysmutex.c	Tue Mar 05 18:01:59 2013 -0500
+++ b/src/thread/pthread/SDL_sysmutex.c	Tue Mar 05 18:54:55 2013 -0500
@@ -22,6 +22,7 @@
 
 #define _GNU_SOURCE
 #include <pthread.h>
+#include <errno.h>
 
 #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;
--- a/src/thread/windows/SDL_sysmutex.c	Tue Mar 05 18:01:59 2013 -0500
+++ b/src/thread/windows/SDL_sysmutex.c	Tue Mar 05 18:54:55 2013 -0500
@@ -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)