@ -395,18 +395,16 @@ static void uv__rwlock_srwlock_wrunlock(uv_rwlock_t* rwlock) {
static int uv__rwlock_fallback_init ( uv_rwlock_t * rwlock ) {
int err ;
err = uv_mutex_init ( & rwlock - > fallback_ . read_mutex_ ) ;
if ( err )
return err ;
/* Initialize the semaphore that acts as the write lock. */
HANDLE handle = CreateSemaphoreW ( NULL , 1 , 1 , NULL ) ;
if ( handle = = NULL )
return uv_translate_sys_error ( GetLastError ( ) ) ;
rwlock - > fallback_ . write_lock_ . sem = handle ;
err = uv_mutex_init ( & rwlock - > fallback_ . write_mutex_ ) ;
if ( err ) {
uv_mutex_destroy ( & rwlock - > fallback_ . read_mutex_ ) ;
return err ;
}
/* Initialize the critical section protecting the reader count. */
InitializeCriticalSection ( & rwlock - > fallback_ . read_lock_ . cs ) ;
/* Initialize the reader count. */
rwlock - > fallback_ . num_readers_ = 0 ;
return 0 ;
@ -414,64 +412,88 @@ static int uv__rwlock_fallback_init(uv_rwlock_t* rwlock) {
static void uv__rwlock_fallback_destroy ( uv_rwlock_t * rwlock ) {
uv_mutex_destroy ( & rwlock - > fallback_ . read_mutex_ ) ;
uv_mutex_destroy ( & rwlock - > fallback_ . write_mutex_ ) ;
DeleteCriticalSection ( & rwlock - > fallback_ . read_lock_ . cs ) ;
CloseHandle ( rwlock - > fallback_ . write_lock_ . sem ) ;
}
static void uv__rwlock_fallback_rdlock ( uv_rwlock_t * rwlock ) {
uv_mutex_lock ( & rwlock - > fallback_ . read_mutex_ ) ;
if ( + + rwlock - > fallback_ . num_readers_ = = 1 )
uv_mutex_lock ( & rwlock - > fallback_ . write_mutex_ ) ;
/* Acquire the lock that protects the reader count. */
EnterCriticalSection ( & rwlock - > fallback_ . read_lock_ . cs ) ;
/* Increase the reader count, and lock for write if this is the first
* reader .
*/
if ( + + rwlock - > fallback_ . num_readers_ = = 1 ) {
DWORD r = WaitForSingleObject ( rwlock - > fallback_ . write_lock_ . sem , INFINITE ) ;
if ( r ! = WAIT_OBJECT_0 )
uv_fatal_error ( GetLastError ( ) , " WaitForSingleObject " ) ;
}
uv_mutex_unlock ( & rwlock - > fallback_ . read_mutex_ ) ;
/* Release the lock that protects the reader count. */
LeaveCriticalSection ( & rwlock - > fallback_ . read_lock_ . cs ) ;
}
static int uv__rwlock_fallback_tryrdlock ( uv_rwlock_t * rwlock ) {
int err ;
err = uv_mutex_trylock ( & rwlock - > fallback_ . read_mutex_ ) ;
if ( err )
goto out ;
if ( ! TryEnterCriticalSection ( & rwlock - > fallback_ . read_lock_ . cs ) )
return UV_EAGAIN ;
err = 0 ;
if ( rwlock - > fallback_ . num_readers_ = = 0 )
err = uv_mutex_trylock ( & rwlock - > fallback_ . write_mutex_ ) ;
if ( err = = 0 )
rwlock - > fallback_ . num_readers_ + + ;
uv_mutex_unlock ( & rwlock - > fallback_ . read_mutex_ ) ;
if ( rwlock - > fallback_ . num_readers_ = = 0 ) {
DWORD r = WaitForSingleObject ( rwlock - > fallback_ . write_lock_ . sem , 0 ) ;
if ( r = = WAIT_OBJECT_0 )
rwlock - > fallback_ . num_readers_ + + ;
else if ( r = = WAIT_TIMEOUT )
err = UV_EAGAIN ;
else if ( r = = WAIT_FAILED )
err = uv_translate_sys_error ( GetLastError ( ) ) ;
else
err = UV_EIO ;
}
out :
LeaveCriticalSection ( & rwlock - > fallback_ . read_lock_ . cs ) ;
return err ;
}
static void uv__rwlock_fallback_rdunlock ( uv_rwlock_t * rwlock ) {
uv_mutex_lock ( & rwlock - > fallback_ . read_mutex_ ) ;
EnterCriticalSection ( & rwlock - > fallback_ . read_lock_ . cs ) ;
if ( - - rwlock - > fallback_ . num_readers_ = = 0 )
uv_mutex_unlock ( & rwlock - > fallback_ . write_mutex_ ) ;
if ( - - rwlock - > fallback_ . num_readers_ = = 0 ) {
if ( ! ReleaseSemaphore ( rwlock - > fallback_ . write_lock_ . sem , 1 , NULL ) )
uv_fatal_error ( GetLastError ( ) , " ReleaseSemaphore " ) ;
}
uv_mutex_unlock ( & rwlock - > fallback_ . read_mutex_ ) ;
LeaveCriticalSection ( & rwlock - > fallback_ . read_lock_ . cs ) ;
}
static void uv__rwlock_fallback_wrlock ( uv_rwlock_t * rwlock ) {
uv_mutex_lock ( & rwlock - > fallback_ . write_mutex_ ) ;
DWORD r = WaitForSingleObject ( rwlock - > fallback_ . write_lock_ . sem , INFINITE ) ;
if ( r ! = WAIT_OBJECT_0 )
uv_fatal_error ( GetLastError ( ) , " WaitForSingleObject " ) ;
}
static int uv__rwlock_fallback_trywrlock ( uv_rwlock_t * rwlock ) {
return uv_mutex_trylock ( & rwlock - > fallback_ . write_mutex_ ) ;
DWORD r = WaitForSingleObject ( rwlock - > fallback_ . write_lock_ . sem , 0 ) ;
if ( r = = WAIT_OBJECT_0 )
return 0 ;
else if ( r = = WAIT_TIMEOUT )
return UV_EAGAIN ;
else if ( r = = WAIT_FAILED )
return uv_translate_sys_error ( GetLastError ( ) ) ;
else
return UV_EIO ;
}
static void uv__rwlock_fallback_wrunlock ( uv_rwlock_t * rwlock ) {
uv_mutex_unlock ( & rwlock - > fallback_ . write_mutex_ ) ;
if ( ! ReleaseSemaphore ( rwlock - > fallback_ . write_lock_ . sem , 1 , NULL ) )
uv_fatal_error ( GetLastError ( ) , " ReleaseSemaphore " ) ;
}