don't crash on Win32

This commit is contained in:
Samuel Neves 2016-05-17 21:40:56 +01:00
parent efb81c7290
commit 998bacf375

View File

@ -76,33 +76,44 @@ _sodium_crit_leave(void)
#elif defined(_WIN32)
static CRITICAL_SECTION *_sodium_lock;
static CRITICAL_SECTION _sodium_lock;
static volatile LONG _sodium_lock_initialized;
static int
_sodium_crit_init(void)
{
LONG status = 0L;
while ((status = InterlockedCompareExchange(&_sodium_lock_initialized,
1L, 0L)) == 1L) {
Sleep(0);
}
switch(status) {
case 0L:
InitializeCriticalSection(&_sodium_lock);
return InterlockedExchange(&_sodium_lock_initialized, 2L) == 1L ? 0 : -1;
case 2L:
return 0;
default: /* should never be reached */
return -1;
}
}
static int
_sodium_crit_enter(void)
{
if (InterlockedCompareExchange(&_sodium_lock_initialized,
1L, 0L) == 0L) {
InitializeCriticalSection(_sodium_lock);
InterlockedIncrement(&_sodium_lock_initialized);
} else {
while (InterlockedCompareExchange(&_sodium_lock_initialized,
2L, 2L) != 2L) {
Sleep(0);
}
if(_sodium_crit_init() != 0) {
return -1;
}
EnterCriticalSection(&_sodium_lock);
return 0;
}
static int
_sodium_crit_leave(void)
{
if (_sodium_lock == NULL) {
return -1;
}
LeaveCriticalSection(_sodium_lock);
LeaveCriticalSection(&_sodium_lock);
return 0;
}