Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Made unix mutexes recursive.
  • Loading branch information
icculus committed Sep 20, 2005
1 parent a1208da commit c28540f
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 7 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG
Expand Up @@ -2,6 +2,8 @@
* CHANGELOG.
*/

09192005 - Make unix mutexes recursive above pthread layer...fixes deadlock on
MacOS X, for now.
09182005 - API BREAKAGE: PHYSFS_enumerateFilesCallback() now passes the
original directory name back to the app in the callback. This
API was only in 1.1.0, and wasn't promised to be stable at this
Expand Down
46 changes: 39 additions & 7 deletions platform/unix.c
Expand Up @@ -466,6 +466,13 @@ void __PHYSFS_platformReleaseMutex(void *mutex) {}

#else

typedef struct
{
pthread_mutex_t mutex;
pthread_t owner;
PHYSFS_uint32 count;
} PthreadMutex;

/* Just in case; this is a panic value. */
#if ((!defined SIZEOF_INT) || (SIZEOF_INT <= 0))
# define SIZEOF_INT 4
Expand All @@ -490,36 +497,61 @@ PHYSFS_uint64 __PHYSFS_platformGetThreadID(void)
void *__PHYSFS_platformCreateMutex(void)
{
int rc;
pthread_mutex_t *m;
m = (pthread_mutex_t *) allocator.Malloc(sizeof (pthread_mutex_t));
PthreadMutex *m = (PthreadMutex *) allocator.Malloc(sizeof (PthreadMutex));
BAIL_IF_MACRO(m == NULL, ERR_OUT_OF_MEMORY, NULL);
rc = pthread_mutex_init(m, 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)
{
pthread_mutex_destroy((pthread_mutex_t *) mutex);
allocator.Free(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)
{
return(pthread_mutex_lock((pthread_mutex_t *) mutex) == 0);
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)
{
pthread_mutex_unlock((pthread_mutex_t *) 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_PTHREADS_SUPPORT */
Expand Down

0 comments on commit c28540f

Please sign in to comment.