src/thread/windows/SDL_sysmutex.c
changeset 5335 2bb1233924f1
parent 5262 b530ef003506
child 5336 66d3c4a6d6f8
equal deleted inserted replaced
5333:5d3a2cd4e8c9 5335:2bb1233924f1
    28 #include "SDL_mutex.h"
    28 #include "SDL_mutex.h"
    29 
    29 
    30 
    30 
    31 struct SDL_mutex
    31 struct SDL_mutex
    32 {
    32 {
    33     HANDLE id;
    33     CRITICAL_SECTION cs;
    34 };
    34 };
    35 
    35 
    36 /* Create a mutex */
    36 /* Create a mutex */
    37 SDL_mutex *
    37 SDL_mutex *
    38 SDL_CreateMutex(void)
    38 SDL_CreateMutex(void)
    39 {
    39 {
    40     SDL_mutex *mutex;
    40     SDL_mutex *mutex;
       
    41     static DWORD (WINAPI*pf_SetCriticalSectionSpinCount)(LPCRITICAL_SECTION, DWORD) = NULL;
       
    42     static HMODULE kernel32 = NULL;
       
    43 
       
    44     /* One time logic - detect WinNT */
       
    45     if(kernel32 == NULL) {
       
    46         kernel32 = GetModuleHandleA("kernel32.dll");
       
    47 		if(kernel32) {
       
    48             /* Attempt to resolve symbol -- Win9x gets NULL */
       
    49             pf_SetCriticalSectionSpinCount = (DWORD (WINAPI*)(LPCRITICAL_SECTION, DWORD))GetProcAddress(kernel32, "SetCriticalSectionSpinCount");
       
    50         }
       
    51 		else
       
    52 			kernel32 = (HMODULE)0x01; /* don't try to init again */
       
    53 	}
       
    54 
    41 
    55 
    42     /* Allocate mutex memory */
    56     /* Allocate mutex memory */
    43     mutex = (SDL_mutex *) SDL_malloc(sizeof(*mutex));
    57     mutex = (SDL_mutex *) SDL_malloc(sizeof(*mutex));
    44     if (mutex) {
    58     if (mutex) {
    45         /* Create the mutex, with initial value signaled */
    59         /* Initialize */
    46         mutex->id = CreateMutex(NULL, FALSE, NULL);
    60         InitializeCriticalSection(&mutex->cs);
    47         if (!mutex->id) {
    61 
    48             SDL_SetError("Couldn't create mutex");
    62         /* On SMP systems, a non-zero spin count generally helps performance */
    49             SDL_free(mutex);
    63         if(pf_SetCriticalSectionSpinCount) pf_SetCriticalSectionSpinCount(&mutex->cs, 2000);
    50             mutex = NULL;
       
    51         }
       
    52     } else {
    64     } else {
    53         SDL_OutOfMemory();
    65         SDL_OutOfMemory();
    54     }
    66     }
    55     return (mutex);
    67     return (mutex);
    56 }
    68 }
    58 /* Free the mutex */
    70 /* Free the mutex */
    59 void
    71 void
    60 SDL_DestroyMutex(SDL_mutex * mutex)
    72 SDL_DestroyMutex(SDL_mutex * mutex)
    61 {
    73 {
    62     if (mutex) {
    74     if (mutex) {
    63         if (mutex->id) {
    75         DeleteCriticalSection(&mutex->cs);
    64             CloseHandle(mutex->id);
       
    65             mutex->id = 0;
       
    66         }
       
    67         SDL_free(mutex);
    76         SDL_free(mutex);
    68     }
    77     }
    69 }
    78 }
    70 
    79 
    71 /* Lock the mutex */
    80 /* Lock the mutex */
    74 {
    83 {
    75     if (mutex == NULL) {
    84     if (mutex == NULL) {
    76         SDL_SetError("Passed a NULL mutex");
    85         SDL_SetError("Passed a NULL mutex");
    77         return -1;
    86         return -1;
    78     }
    87     }
    79     if (WaitForSingleObject(mutex->id, INFINITE) == WAIT_FAILED) {
    88 
    80         SDL_SetError("Couldn't wait on mutex");
    89     EnterCriticalSection(&mutex->cs);
    81         return -1;
       
    82     }
       
    83     return (0);
    90     return (0);
    84 }
    91 }
    85 
    92 
    86 /* Unlock the mutex */
    93 /* Unlock the mutex */
    87 int
    94 int
    89 {
    96 {
    90     if (mutex == NULL) {
    97     if (mutex == NULL) {
    91         SDL_SetError("Passed a NULL mutex");
    98         SDL_SetError("Passed a NULL mutex");
    92         return -1;
    99         return -1;
    93     }
   100     }
    94     if (ReleaseMutex(mutex->id) == FALSE) {
   101 
    95         SDL_SetError("Couldn't release mutex");
   102     LeaveCriticalSection(&mutex->cs);
    96         return -1;
       
    97     }
       
    98     return (0);
   103     return (0);
    99 }
   104 }
   100 
   105 
   101 /* vi: set ts=4 sw=4 expandtab: */
   106 /* vi: set ts=4 sw=4 expandtab: */