src/thread/windows/SDL_syssem.c
author Ryan C. Gordon
Sat, 15 Sep 2012 10:59:39 -0400
changeset 6430 48d519500f7e
parent 6138 4c64952a58fb
child 6885 700f1b25f77f
permissions -rwxr-xr-x
Removed Windows CE support from SDL 2.0.

It's a long-dead platform, and we don't have any way to build for, test, or
maintain it, so there's no sense in doing acrobatics to support it.

If you need Windows CE support, use SDL 1.2. If you need Windows Phone support,
send SDL 2.0 patches for the newer Windows Mobile platform.
slouken@0
     1
/*
slouken@5535
     2
  Simple DirectMedia Layer
slouken@6138
     3
  Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
slouken@0
     4
slouken@5535
     5
  This software is provided 'as-is', without any express or implied
slouken@5535
     6
  warranty.  In no event will the authors be held liable for any damages
slouken@5535
     7
  arising from the use of this software.
slouken@0
     8
slouken@5535
     9
  Permission is granted to anyone to use this software for any purpose,
slouken@5535
    10
  including commercial applications, and to alter it and redistribute it
slouken@5535
    11
  freely, subject to the following restrictions:
slouken@0
    12
slouken@5535
    13
  1. The origin of this software must not be misrepresented; you must not
slouken@5535
    14
     claim that you wrote the original software. If you use this software
slouken@5535
    15
     in a product, an acknowledgment in the product documentation would be
slouken@5535
    16
     appreciated but is not required.
slouken@5535
    17
  2. Altered source versions must be plainly marked as such, and must not be
slouken@5535
    18
     misrepresented as being the original software.
slouken@5535
    19
  3. This notice may not be removed or altered from any source distribution.
slouken@0
    20
*/
slouken@1402
    21
#include "SDL_config.h"
slouken@0
    22
slouken@6044
    23
#if SDL_THREAD_WINDOWS
slouken@6044
    24
slouken@0
    25
/* Semaphore functions using the Win32 API */
slouken@0
    26
slouken@5090
    27
#include "../../core/windows/SDL_windows.h"
slouken@0
    28
slouken@0
    29
#include "SDL_thread.h"
slouken@0
    30
slouken@1895
    31
struct SDL_semaphore
slouken@1895
    32
{
slouken@1895
    33
    HANDLE id;
slouken@5086
    34
    LONG count;
slouken@0
    35
};
slouken@0
    36
slouken@0
    37
slouken@0
    38
/* Create a semaphore */
slouken@1895
    39
SDL_sem *
slouken@1895
    40
SDL_CreateSemaphore(Uint32 initial_value)
slouken@0
    41
{
slouken@1895
    42
    SDL_sem *sem;
slouken@0
    43
slouken@1895
    44
    /* Allocate sem memory */
slouken@1895
    45
    sem = (SDL_sem *) SDL_malloc(sizeof(*sem));
slouken@1895
    46
    if (sem) {
slouken@1895
    47
        /* Create the semaphore, with max value 32K */
slouken@1895
    48
        sem->id = CreateSemaphore(NULL, initial_value, 32 * 1024, NULL);
slouken@1895
    49
        sem->count = initial_value;
slouken@1895
    50
        if (!sem->id) {
slouken@1895
    51
            SDL_SetError("Couldn't create semaphore");
slouken@1895
    52
            SDL_free(sem);
slouken@1895
    53
            sem = NULL;
slouken@1895
    54
        }
slouken@1895
    55
    } else {
slouken@1895
    56
        SDL_OutOfMemory();
slouken@1895
    57
    }
slouken@1895
    58
    return (sem);
slouken@0
    59
}
slouken@0
    60
slouken@0
    61
/* Free the semaphore */
slouken@1895
    62
void
slouken@1895
    63
SDL_DestroySemaphore(SDL_sem * sem)
slouken@0
    64
{
slouken@1895
    65
    if (sem) {
slouken@1895
    66
        if (sem->id) {
slouken@1895
    67
            CloseHandle(sem->id);
slouken@1895
    68
            sem->id = 0;
slouken@1895
    69
        }
slouken@1895
    70
        SDL_free(sem);
slouken@1895
    71
    }
slouken@0
    72
}
slouken@0
    73
slouken@1895
    74
int
slouken@1895
    75
SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout)
slouken@0
    76
{
slouken@1895
    77
    int retval;
slouken@1895
    78
    DWORD dwMilliseconds;
slouken@0
    79
slouken@1895
    80
    if (!sem) {
slouken@1895
    81
        SDL_SetError("Passed a NULL sem");
slouken@1895
    82
        return -1;
slouken@1895
    83
    }
slouken@0
    84
slouken@1895
    85
    if (timeout == SDL_MUTEX_MAXWAIT) {
slouken@1895
    86
        dwMilliseconds = INFINITE;
slouken@1895
    87
    } else {
slouken@1895
    88
        dwMilliseconds = (DWORD) timeout;
slouken@1895
    89
    }
slouken@1895
    90
    switch (WaitForSingleObject(sem->id, dwMilliseconds)) {
slouken@1895
    91
    case WAIT_OBJECT_0:
slouken@3069
    92
        InterlockedDecrement(&sem->count);
slouken@1895
    93
        retval = 0;
slouken@1895
    94
        break;
slouken@1895
    95
    case WAIT_TIMEOUT:
slouken@1895
    96
        retval = SDL_MUTEX_TIMEDOUT;
slouken@1895
    97
        break;
slouken@1895
    98
    default:
slouken@1895
    99
        SDL_SetError("WaitForSingleObject() failed");
slouken@1895
   100
        retval = -1;
slouken@1895
   101
        break;
slouken@1895
   102
    }
slouken@1895
   103
    return retval;
slouken@0
   104
}
slouken@0
   105
slouken@1895
   106
int
slouken@1895
   107
SDL_SemTryWait(SDL_sem * sem)
slouken@0
   108
{
slouken@1895
   109
    return SDL_SemWaitTimeout(sem, 0);
slouken@0
   110
}
slouken@0
   111
slouken@1895
   112
int
slouken@1895
   113
SDL_SemWait(SDL_sem * sem)
slouken@0
   114
{
slouken@1895
   115
    return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
slouken@0
   116
}
slouken@0
   117
slouken@0
   118
/* Returns the current count of the semaphore */
slouken@1895
   119
Uint32
slouken@1895
   120
SDL_SemValue(SDL_sem * sem)
slouken@0
   121
{
slouken@1895
   122
    if (!sem) {
slouken@1895
   123
        SDL_SetError("Passed a NULL sem");
slouken@1895
   124
        return 0;
slouken@1895
   125
    }
slouken@4475
   126
    return (Uint32)sem->count;
slouken@0
   127
}
slouken@0
   128
slouken@1895
   129
int
slouken@1895
   130
SDL_SemPost(SDL_sem * sem)
slouken@0
   131
{
slouken@1895
   132
    if (!sem) {
slouken@1895
   133
        SDL_SetError("Passed a NULL sem");
slouken@1895
   134
        return -1;
slouken@1895
   135
    }
slouken@1895
   136
    /* Increase the counter in the first place, because
slouken@1895
   137
     * after a successful release the semaphore may
slouken@1895
   138
     * immediately get destroyed by another thread which
slouken@1895
   139
     * is waiting for this semaphore.
slouken@1895
   140
     */
slouken@3069
   141
    InterlockedIncrement(&sem->count);
slouken@1895
   142
    if (ReleaseSemaphore(sem->id, 1, NULL) == FALSE) {
slouken@3071
   143
        InterlockedDecrement(&sem->count);      /* restore */
slouken@1895
   144
        SDL_SetError("ReleaseSemaphore() failed");
slouken@1895
   145
        return -1;
slouken@1895
   146
    }
slouken@1895
   147
    return 0;
slouken@0
   148
}
slouken@1895
   149
slouken@6044
   150
#endif /* SDL_THREAD_WINDOWS */
slouken@6044
   151
slouken@1895
   152
/* vi: set ts=4 sw=4 expandtab: */