src/thread/stdcpp/SDL_sysmutex.cpp
changeset 8357 8d788bb003f2
parent 8356 4d85eba58f0a
child 8360 7f1bc00e59fc
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/thread/stdcpp/SDL_sysmutex.cpp	Thu Nov 22 23:12:06 2012 -0500
     1.3 @@ -0,0 +1,139 @@
     1.4 +/*
     1.5 +  Simple DirectMedia Layer
     1.6 +  Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
     1.7 +
     1.8 +  This software is provided 'as-is', without any express or implied
     1.9 +  warranty.  In no event will the authors be held liable for any damages
    1.10 +  arising from the use of this software.
    1.11 +
    1.12 +  Permission is granted to anyone to use this software for any purpose,
    1.13 +  including commercial applications, and to alter it and redistribute it
    1.14 +  freely, subject to the following restrictions:
    1.15 +
    1.16 +  1. The origin of this software must not be misrepresented; you must not
    1.17 +     claim that you wrote the original software. If you use this software
    1.18 +     in a product, an acknowledgment in the product documentation would be
    1.19 +     appreciated but is not required.
    1.20 +  2. Altered source versions must be plainly marked as such, and must not be
    1.21 +     misrepresented as being the original software.
    1.22 +  3. This notice may not be removed or altered from any source distribution.
    1.23 +*/
    1.24 +#include "SDL_config.h"
    1.25 +
    1.26 +/* An implementation of mutexes using semaphores */
    1.27 +
    1.28 +#include "SDL_thread.h"
    1.29 +#include "SDL_systhread_c.h"
    1.30 +
    1.31 +
    1.32 +struct SDL_mutex
    1.33 +{
    1.34 +    int recursive;
    1.35 +    SDL_threadID owner;
    1.36 +    SDL_sem *sem;
    1.37 +};
    1.38 +
    1.39 +/* Create a mutex */
    1.40 +extern "C"
    1.41 +SDL_mutex *
    1.42 +SDL_CreateMutex(void)
    1.43 +{
    1.44 +    SDL_mutex *mutex;
    1.45 +
    1.46 +    /* Allocate mutex memory */
    1.47 +    mutex = (SDL_mutex *) SDL_malloc(sizeof(*mutex));
    1.48 +    if (mutex) {
    1.49 +        /* Create the mutex semaphore, with initial value 1 */
    1.50 +        mutex->sem = SDL_CreateSemaphore(1);
    1.51 +        mutex->recursive = 0;
    1.52 +        mutex->owner = 0;
    1.53 +        if (!mutex->sem) {
    1.54 +            SDL_free(mutex);
    1.55 +            mutex = NULL;
    1.56 +        }
    1.57 +    } else {
    1.58 +        SDL_OutOfMemory();
    1.59 +    }
    1.60 +    return mutex;
    1.61 +}
    1.62 +
    1.63 +/* Free the mutex */
    1.64 +extern "C"
    1.65 +void
    1.66 +SDL_DestroyMutex(SDL_mutex * mutex)
    1.67 +{
    1.68 +    if (mutex) {
    1.69 +        if (mutex->sem) {
    1.70 +            SDL_DestroySemaphore(mutex->sem);
    1.71 +        }
    1.72 +        SDL_free(mutex);
    1.73 +    }
    1.74 +}
    1.75 +
    1.76 +/* Lock the semaphore */
    1.77 +extern "C"
    1.78 +int
    1.79 +SDL_mutexP(SDL_mutex * mutex)
    1.80 +{
    1.81 +#if SDL_THREADS_DISABLED
    1.82 +    return 0;
    1.83 +#else
    1.84 +    SDL_threadID this_thread;
    1.85 +
    1.86 +    if (mutex == NULL) {
    1.87 +        SDL_SetError("Passed a NULL mutex");
    1.88 +        return -1;
    1.89 +    }
    1.90 +
    1.91 +    this_thread = SDL_ThreadID();
    1.92 +    if (mutex->owner == this_thread) {
    1.93 +        ++mutex->recursive;
    1.94 +    } else {
    1.95 +        /* The order of operations is important.
    1.96 +           We set the locking thread id after we obtain the lock
    1.97 +           so unlocks from other threads will fail.
    1.98 +         */
    1.99 +        SDL_SemWait(mutex->sem);
   1.100 +        mutex->owner = this_thread;
   1.101 +        mutex->recursive = 0;
   1.102 +    }
   1.103 +
   1.104 +    return 0;
   1.105 +#endif /* SDL_THREADS_DISABLED */
   1.106 +}
   1.107 +
   1.108 +/* Unlock the mutex */
   1.109 +extern "C"
   1.110 +int
   1.111 +SDL_mutexV(SDL_mutex * mutex)
   1.112 +{
   1.113 +#if SDL_THREADS_DISABLED
   1.114 +    return 0;
   1.115 +#else
   1.116 +    if (mutex == NULL) {
   1.117 +        SDL_SetError("Passed a NULL mutex");
   1.118 +        return -1;
   1.119 +    }
   1.120 +
   1.121 +    /* If we don't own the mutex, we can't unlock it */
   1.122 +    if (SDL_ThreadID() != mutex->owner) {
   1.123 +        SDL_SetError("mutex not owned by this thread");
   1.124 +        return -1;
   1.125 +    }
   1.126 +
   1.127 +    if (mutex->recursive) {
   1.128 +        --mutex->recursive;
   1.129 +    } else {
   1.130 +        /* The order of operations is important.
   1.131 +           First reset the owner so another thread doesn't lock
   1.132 +           the mutex and set the ownership before we reset it,
   1.133 +           then release the lock semaphore.
   1.134 +         */
   1.135 +        mutex->owner = 0;
   1.136 +        SDL_SemPost(mutex->sem);
   1.137 +    }
   1.138 +    return 0;
   1.139 +#endif /* SDL_THREADS_DISABLED */
   1.140 +}
   1.141 +
   1.142 +/* vi: set ts=4 sw=4 expandtab: */