src/thread/windows/SDL_syssem.c
author Sam Lantinga
Mon, 24 Jan 2011 21:20:30 -0800
changeset 5090 327f181542f1
parent 5086 c2539ff054c8
child 5262 b530ef003506
permissions -rw-r--r--
Include windows.h in a single point in the source, so we can be consistent about the definition of UNICODE and have core utility functions for Windows that all modules can share.

I think this also fixes the bug relating to non-latin characters in filenames, since UNICODE wasn't defined in SDL_rwops.c
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2010 Sam Lantinga
     4 
     5     This library is free software; you can redistribute it and/or
     6     modify it under the terms of the GNU Lesser General Public
     7     License as published by the Free Software Foundation; either
     8     version 2.1 of the License, or (at your option) any later version.
     9 
    10     This library is distributed in the hope that it will be useful,
    11     but WITHOUT ANY WARRANTY; without even the implied warranty of
    12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    13     Lesser General Public License for more details.
    14 
    15     You should have received a copy of the GNU Lesser General Public
    16     License along with this library; if not, write to the Free Software
    17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    18 
    19     Sam Lantinga
    20     slouken@libsdl.org
    21 */
    22 #include "SDL_config.h"
    23 
    24 /* Semaphore functions using the Win32 API */
    25 
    26 #include "../../core/windows/SDL_windows.h"
    27 
    28 #include "SDL_thread.h"
    29 #if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
    30 #include "win_ce_semaphore.h"
    31 #endif
    32 
    33 
    34 struct SDL_semaphore
    35 {
    36 #if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
    37     SYNCHHANDLE id;
    38 #else
    39     HANDLE id;
    40 #endif
    41     LONG count;
    42 };
    43 
    44 
    45 /* Create a semaphore */
    46 SDL_sem *
    47 SDL_CreateSemaphore(Uint32 initial_value)
    48 {
    49     SDL_sem *sem;
    50 
    51     /* Allocate sem memory */
    52     sem = (SDL_sem *) SDL_malloc(sizeof(*sem));
    53     if (sem) {
    54         /* Create the semaphore, with max value 32K */
    55 #if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
    56         sem->id = CreateSemaphoreCE(NULL, initial_value, 32 * 1024, NULL);
    57 #else
    58         sem->id = CreateSemaphore(NULL, initial_value, 32 * 1024, NULL);
    59 #endif
    60         sem->count = initial_value;
    61         if (!sem->id) {
    62             SDL_SetError("Couldn't create semaphore");
    63             SDL_free(sem);
    64             sem = NULL;
    65         }
    66     } else {
    67         SDL_OutOfMemory();
    68     }
    69     return (sem);
    70 }
    71 
    72 /* Free the semaphore */
    73 void
    74 SDL_DestroySemaphore(SDL_sem * sem)
    75 {
    76     if (sem) {
    77         if (sem->id) {
    78 #if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
    79             CloseSynchHandle(sem->id);
    80 #else
    81             CloseHandle(sem->id);
    82 #endif
    83             sem->id = 0;
    84         }
    85         SDL_free(sem);
    86     }
    87 }
    88 
    89 int
    90 SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout)
    91 {
    92     int retval;
    93     DWORD dwMilliseconds;
    94 
    95     if (!sem) {
    96         SDL_SetError("Passed a NULL sem");
    97         return -1;
    98     }
    99 
   100     if (timeout == SDL_MUTEX_MAXWAIT) {
   101         dwMilliseconds = INFINITE;
   102     } else {
   103         dwMilliseconds = (DWORD) timeout;
   104     }
   105 #if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
   106     switch (WaitForSemaphoreCE(sem->id, dwMilliseconds)) {
   107 #else
   108     switch (WaitForSingleObject(sem->id, dwMilliseconds)) {
   109 #endif
   110     case WAIT_OBJECT_0:
   111         InterlockedDecrement(&sem->count);
   112         retval = 0;
   113         break;
   114     case WAIT_TIMEOUT:
   115         retval = SDL_MUTEX_TIMEDOUT;
   116         break;
   117     default:
   118         SDL_SetError("WaitForSingleObject() failed");
   119         retval = -1;
   120         break;
   121     }
   122     return retval;
   123 }
   124 
   125 int
   126 SDL_SemTryWait(SDL_sem * sem)
   127 {
   128     return SDL_SemWaitTimeout(sem, 0);
   129 }
   130 
   131 int
   132 SDL_SemWait(SDL_sem * sem)
   133 {
   134     return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
   135 }
   136 
   137 /* Returns the current count of the semaphore */
   138 Uint32
   139 SDL_SemValue(SDL_sem * sem)
   140 {
   141     if (!sem) {
   142         SDL_SetError("Passed a NULL sem");
   143         return 0;
   144     }
   145     return (Uint32)sem->count;
   146 }
   147 
   148 int
   149 SDL_SemPost(SDL_sem * sem)
   150 {
   151     if (!sem) {
   152         SDL_SetError("Passed a NULL sem");
   153         return -1;
   154     }
   155     /* Increase the counter in the first place, because
   156      * after a successful release the semaphore may
   157      * immediately get destroyed by another thread which
   158      * is waiting for this semaphore.
   159      */
   160     InterlockedIncrement(&sem->count);
   161 #if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
   162     if (ReleaseSemaphoreCE(sem->id, 1, NULL) == FALSE) {
   163 #else
   164     if (ReleaseSemaphore(sem->id, 1, NULL) == FALSE) {
   165 #endif
   166         InterlockedDecrement(&sem->count);      /* restore */
   167         SDL_SetError("ReleaseSemaphore() failed");
   168         return -1;
   169     }
   170     return 0;
   171 }
   172 
   173 /* vi: set ts=4 sw=4 expandtab: */