src/platform_posix.c
changeset 1173 77b2df665bd1
parent 1167 9d84f8652839
child 1176 367c1f9a996c
--- a/src/platform_posix.c	Sat Jul 16 14:14:00 2011 +0000
+++ b/src/platform_posix.c	Mon Jul 25 11:29:44 2011 -0700
@@ -20,6 +20,10 @@
 #include <errno.h>
 #include <fcntl.h>
 
+#if ((!defined PHYSFS_NO_THREAD_SUPPORT) && (!defined PHYSFS_PLATFORM_BEOS))
+#include <pthread.h>
+#endif
+
 #ifdef PHYSFS_HAVE_LLSEEK
 #include <linux/unistd.h>
 #endif
@@ -433,6 +437,95 @@
     return 1;
 } /* __PHYSFS_platformStat */
 
+
+#ifndef PHYSFS_PLATFORM_BEOS  /* BeOS has its own code in platform_beos.cpp */
+#if (defined PHYSFS_NO_THREAD_SUPPORT)
+
+void *__PHYSFS_platformGetThreadID(void) { return ((void *) 0x0001); }
+void *__PHYSFS_platformCreateMutex(void) { return ((void *) 0x0001); }
+void __PHYSFS_platformDestroyMutex(void *mutex) {}
+int __PHYSFS_platformGrabMutex(void *mutex) { return 1; }
+void __PHYSFS_platformReleaseMutex(void *mutex) {}
+
+#else
+
+typedef struct
+{
+    pthread_mutex_t mutex;
+    pthread_t owner;
+    PHYSFS_uint32 count;
+} PthreadMutex;
+
+
+void *__PHYSFS_platformGetThreadID(void)
+{
+    return ( (void *) ((size_t) pthread_self()) );
+} /* __PHYSFS_platformGetThreadID */
+
+
+void *__PHYSFS_platformCreateMutex(void)
+{
+    int rc;
+    PthreadMutex *m = (PthreadMutex *) allocator.Malloc(sizeof (PthreadMutex));
+    BAIL_IF_MACRO(m == NULL, ERR_OUT_OF_MEMORY, NULL);
+    rc = pthread_mutex_init(&m->mutex, NULL);
+    if (rc != 0)
+    {
+        allocator.Free(m);
+        BAIL_MACRO(strerror(rc), NULL);
+    } /* if */
+
+    m->count = 0;
+    m->owner = (pthread_t) 0xDEADBEEF;
+    return ((void *) m);
+} /* __PHYSFS_platformCreateMutex */
+
+
+void __PHYSFS_platformDestroyMutex(void *mutex)
+{
+    PthreadMutex *m = (PthreadMutex *) mutex;
+
+    /* Destroying a locked mutex is a bug, but we'll try to be helpful. */
+    if ((m->owner == pthread_self()) && (m->count > 0))
+        pthread_mutex_unlock(&m->mutex);
+
+    pthread_mutex_destroy(&m->mutex);
+    allocator.Free(m);
+} /* __PHYSFS_platformDestroyMutex */
+
+
+int __PHYSFS_platformGrabMutex(void *mutex)
+{
+    PthreadMutex *m = (PthreadMutex *) mutex;
+    pthread_t tid = pthread_self();
+    if (m->owner != tid)
+    {
+        if (pthread_mutex_lock(&m->mutex) != 0)
+            return 0;
+        m->owner = tid;
+    } /* if */
+
+    m->count++;
+    return 1;
+} /* __PHYSFS_platformGrabMutex */
+
+
+void __PHYSFS_platformReleaseMutex(void *mutex)
+{
+    PthreadMutex *m = (PthreadMutex *) mutex;
+    if (m->owner == pthread_self())
+    {
+        if (--m->count == 0)
+        {
+            m->owner = (pthread_t) 0xDEADBEEF;
+            pthread_mutex_unlock(&m->mutex);
+        } /* if */
+    } /* if */
+} /* __PHYSFS_platformReleaseMutex */
+
+#endif /* !PHYSFS_NO_THREAD_SUPPORT */
+#endif /* !PHYSFS_PLATFORM_BEOS */
+
 #endif  /* PHYSFS_PLATFORM_POSIX */
 
 /* end of posix.c ... */