src/thread/stdcpp/SDL_sysmutex.cpp
author David Ludwig
Thu, 22 Nov 2012 23:12:06 -0500
changeset 8357 8d788bb003f2
parent 8356 src/thread/stdcpp/SDL_sysmutex.c@4d85eba58f0a
child 8360 7f1bc00e59fc
permissions -rw-r--r--
WinRT: made the skeleton C++11 thread implementation use .cpp files, not .c
dludwig@8356
     1
/*
dludwig@8356
     2
  Simple DirectMedia Layer
dludwig@8356
     3
  Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
dludwig@8356
     4
dludwig@8356
     5
  This software is provided 'as-is', without any express or implied
dludwig@8356
     6
  warranty.  In no event will the authors be held liable for any damages
dludwig@8356
     7
  arising from the use of this software.
dludwig@8356
     8
dludwig@8356
     9
  Permission is granted to anyone to use this software for any purpose,
dludwig@8356
    10
  including commercial applications, and to alter it and redistribute it
dludwig@8356
    11
  freely, subject to the following restrictions:
dludwig@8356
    12
dludwig@8356
    13
  1. The origin of this software must not be misrepresented; you must not
dludwig@8356
    14
     claim that you wrote the original software. If you use this software
dludwig@8356
    15
     in a product, an acknowledgment in the product documentation would be
dludwig@8356
    16
     appreciated but is not required.
dludwig@8356
    17
  2. Altered source versions must be plainly marked as such, and must not be
dludwig@8356
    18
     misrepresented as being the original software.
dludwig@8356
    19
  3. This notice may not be removed or altered from any source distribution.
dludwig@8356
    20
*/
dludwig@8356
    21
#include "SDL_config.h"
dludwig@8356
    22
dludwig@8356
    23
/* An implementation of mutexes using semaphores */
dludwig@8356
    24
dludwig@8356
    25
#include "SDL_thread.h"
dludwig@8356
    26
#include "SDL_systhread_c.h"
dludwig@8356
    27
dludwig@8356
    28
dludwig@8356
    29
struct SDL_mutex
dludwig@8356
    30
{
dludwig@8356
    31
    int recursive;
dludwig@8356
    32
    SDL_threadID owner;
dludwig@8356
    33
    SDL_sem *sem;
dludwig@8356
    34
};
dludwig@8356
    35
dludwig@8356
    36
/* Create a mutex */
dludwig@8357
    37
extern "C"
dludwig@8356
    38
SDL_mutex *
dludwig@8356
    39
SDL_CreateMutex(void)
dludwig@8356
    40
{
dludwig@8356
    41
    SDL_mutex *mutex;
dludwig@8356
    42
dludwig@8356
    43
    /* Allocate mutex memory */
dludwig@8356
    44
    mutex = (SDL_mutex *) SDL_malloc(sizeof(*mutex));
dludwig@8356
    45
    if (mutex) {
dludwig@8356
    46
        /* Create the mutex semaphore, with initial value 1 */
dludwig@8356
    47
        mutex->sem = SDL_CreateSemaphore(1);
dludwig@8356
    48
        mutex->recursive = 0;
dludwig@8356
    49
        mutex->owner = 0;
dludwig@8356
    50
        if (!mutex->sem) {
dludwig@8356
    51
            SDL_free(mutex);
dludwig@8356
    52
            mutex = NULL;
dludwig@8356
    53
        }
dludwig@8356
    54
    } else {
dludwig@8356
    55
        SDL_OutOfMemory();
dludwig@8356
    56
    }
dludwig@8356
    57
    return mutex;
dludwig@8356
    58
}
dludwig@8356
    59
dludwig@8356
    60
/* Free the mutex */
dludwig@8357
    61
extern "C"
dludwig@8356
    62
void
dludwig@8356
    63
SDL_DestroyMutex(SDL_mutex * mutex)
dludwig@8356
    64
{
dludwig@8356
    65
    if (mutex) {
dludwig@8356
    66
        if (mutex->sem) {
dludwig@8356
    67
            SDL_DestroySemaphore(mutex->sem);
dludwig@8356
    68
        }
dludwig@8356
    69
        SDL_free(mutex);
dludwig@8356
    70
    }
dludwig@8356
    71
}
dludwig@8356
    72
dludwig@8356
    73
/* Lock the semaphore */
dludwig@8357
    74
extern "C"
dludwig@8356
    75
int
dludwig@8356
    76
SDL_mutexP(SDL_mutex * mutex)
dludwig@8356
    77
{
dludwig@8356
    78
#if SDL_THREADS_DISABLED
dludwig@8356
    79
    return 0;
dludwig@8356
    80
#else
dludwig@8356
    81
    SDL_threadID this_thread;
dludwig@8356
    82
dludwig@8356
    83
    if (mutex == NULL) {
dludwig@8356
    84
        SDL_SetError("Passed a NULL mutex");
dludwig@8356
    85
        return -1;
dludwig@8356
    86
    }
dludwig@8356
    87
dludwig@8356
    88
    this_thread = SDL_ThreadID();
dludwig@8356
    89
    if (mutex->owner == this_thread) {
dludwig@8356
    90
        ++mutex->recursive;
dludwig@8356
    91
    } else {
dludwig@8356
    92
        /* The order of operations is important.
dludwig@8356
    93
           We set the locking thread id after we obtain the lock
dludwig@8356
    94
           so unlocks from other threads will fail.
dludwig@8356
    95
         */
dludwig@8356
    96
        SDL_SemWait(mutex->sem);
dludwig@8356
    97
        mutex->owner = this_thread;
dludwig@8356
    98
        mutex->recursive = 0;
dludwig@8356
    99
    }
dludwig@8356
   100
dludwig@8356
   101
    return 0;
dludwig@8356
   102
#endif /* SDL_THREADS_DISABLED */
dludwig@8356
   103
}
dludwig@8356
   104
dludwig@8356
   105
/* Unlock the mutex */
dludwig@8357
   106
extern "C"
dludwig@8356
   107
int
dludwig@8356
   108
SDL_mutexV(SDL_mutex * mutex)
dludwig@8356
   109
{
dludwig@8356
   110
#if SDL_THREADS_DISABLED
dludwig@8356
   111
    return 0;
dludwig@8356
   112
#else
dludwig@8356
   113
    if (mutex == NULL) {
dludwig@8356
   114
        SDL_SetError("Passed a NULL mutex");
dludwig@8356
   115
        return -1;
dludwig@8356
   116
    }
dludwig@8356
   117
dludwig@8356
   118
    /* If we don't own the mutex, we can't unlock it */
dludwig@8356
   119
    if (SDL_ThreadID() != mutex->owner) {
dludwig@8356
   120
        SDL_SetError("mutex not owned by this thread");
dludwig@8356
   121
        return -1;
dludwig@8356
   122
    }
dludwig@8356
   123
dludwig@8356
   124
    if (mutex->recursive) {
dludwig@8356
   125
        --mutex->recursive;
dludwig@8356
   126
    } else {
dludwig@8356
   127
        /* The order of operations is important.
dludwig@8356
   128
           First reset the owner so another thread doesn't lock
dludwig@8356
   129
           the mutex and set the ownership before we reset it,
dludwig@8356
   130
           then release the lock semaphore.
dludwig@8356
   131
         */
dludwig@8356
   132
        mutex->owner = 0;
dludwig@8356
   133
        SDL_SemPost(mutex->sem);
dludwig@8356
   134
    }
dludwig@8356
   135
    return 0;
dludwig@8356
   136
#endif /* SDL_THREADS_DISABLED */
dludwig@8356
   137
}
dludwig@8356
   138
dludwig@8356
   139
/* vi: set ts=4 sw=4 expandtab: */