Switch Windows CRYPTO_MUTEX implementation to SRWLOCK.

Now that we no longer support Windows XP, this is available.
Unfortunately, the public header version of CRYPTO_MUTEX means we
still can't easily merge CRYPTO_MUTEX and CRYPTO_STATIC_MUTEX.

BUG=37

Change-Id: If309de3f06e0854c505083b72fd64d1dbb3f4563
Reviewed-on: https://boringssl-review.googlesource.com/8081
Reviewed-by: Adam Langley <agl@google.com>
This commit is contained in:
David Benjamin 2016-05-24 15:41:11 +00:00 committed by Adam Langley
parent 29270dea85
commit 156edfe536
3 changed files with 18 additions and 42 deletions

View File

@ -355,12 +355,8 @@ OPENSSL_EXPORT int CRYPTO_refcount_dec_and_test_zero(CRYPTO_refcount_t *count);
* |CRYPTO_STATIC_MUTEX_INIT|.
*
* |CRYPTO_MUTEX| can appear in public structures and so is defined in
* thread.h.
*
* The global lock is a different type because there's no static initialiser
* value on Windows for locks, so global locks have to be coupled with a
* |CRYPTO_once_t| to ensure that the lock is setup before use. This is done
* automatically by |CRYPTO_STATIC_MUTEX_lock_*|. */
* thread.h as a structure large enough to fit the real type. The global lock is
* a different type so it may be initialized with platform initializer macros.*/
#if defined(OPENSSL_NO_THREADS)
struct CRYPTO_STATIC_MUTEX {
@ -369,10 +365,9 @@ struct CRYPTO_STATIC_MUTEX {
#define CRYPTO_STATIC_MUTEX_INIT { 0 }
#elif defined(OPENSSL_WINDOWS)
struct CRYPTO_STATIC_MUTEX {
CRYPTO_once_t once;
CRITICAL_SECTION lock;
SRWLOCK lock;
};
#define CRYPTO_STATIC_MUTEX_INIT { CRYPTO_ONCE_INIT, { 0 } }
#define CRYPTO_STATIC_MUTEX_INIT { SRWLOCK_INIT }
#else
struct CRYPTO_STATIC_MUTEX {
pthread_rwlock_t lock;
@ -385,8 +380,7 @@ struct CRYPTO_STATIC_MUTEX {
OPENSSL_EXPORT void CRYPTO_MUTEX_init(CRYPTO_MUTEX *lock);
/* CRYPTO_MUTEX_lock_read locks |lock| such that other threads may also have a
* read lock, but none may have a write lock. (On Windows, read locks are
* actually fully exclusive.) */
* read lock, but none may have a write lock. */
OPENSSL_EXPORT void CRYPTO_MUTEX_lock_read(CRYPTO_MUTEX *lock);
/* CRYPTO_MUTEX_lock_write locks |lock| such that no other thread has any type

View File

@ -27,7 +27,7 @@
#include <openssl/type_check.h>
OPENSSL_COMPILE_ASSERT(sizeof(CRYPTO_MUTEX) >= sizeof(CRITICAL_SECTION),
OPENSSL_COMPILE_ASSERT(sizeof(CRYPTO_MUTEX) >= sizeof(SRWLOCK),
CRYPTO_MUTEX_too_small);
static BOOL CALLBACK call_once_init(INIT_ONCE *once, void *arg, void **out) {
@ -43,60 +43,43 @@ void CRYPTO_once(CRYPTO_once_t *once, void (*init)(void)) {
}
void CRYPTO_MUTEX_init(CRYPTO_MUTEX *lock) {
if (!InitializeCriticalSectionAndSpinCount((CRITICAL_SECTION *) lock, 0x400)) {
abort();
}
InitializeSRWLock((SRWLOCK *) lock);
}
void CRYPTO_MUTEX_lock_read(CRYPTO_MUTEX *lock) {
/* Since we have to support Windows XP, read locks are actually exclusive. */
EnterCriticalSection((CRITICAL_SECTION *) lock);
AcquireSRWLockShared((SRWLOCK *) lock);
}
void CRYPTO_MUTEX_lock_write(CRYPTO_MUTEX *lock) {
EnterCriticalSection((CRITICAL_SECTION *) lock);
AcquireSRWLockExclusive((SRWLOCK *) lock);
}
void CRYPTO_MUTEX_unlock_read(CRYPTO_MUTEX *lock) {
LeaveCriticalSection((CRITICAL_SECTION *) lock);
ReleaseSRWLockShared((SRWLOCK *) lock);
}
void CRYPTO_MUTEX_unlock_write(CRYPTO_MUTEX *lock) {
LeaveCriticalSection((CRITICAL_SECTION *) lock);
ReleaseSRWLockExclusive((SRWLOCK *) lock);
}
void CRYPTO_MUTEX_cleanup(CRYPTO_MUTEX *lock) {
DeleteCriticalSection((CRITICAL_SECTION *) lock);
}
static BOOL CALLBACK static_lock_init(INIT_ONCE *once, void *arg, void **out) {
struct CRYPTO_STATIC_MUTEX *lock = arg;
if (!InitializeCriticalSectionAndSpinCount(&lock->lock, 0x400)) {
abort();
}
return TRUE;
/* SRWLOCKs require no cleanup. */
}
void CRYPTO_STATIC_MUTEX_lock_read(struct CRYPTO_STATIC_MUTEX *lock) {
/* TODO(davidben): Consider replacing these with SRWLOCK now that we no longer
* need to support Windows XP. Currently, read locks are actually
* exclusive. */
if (!InitOnceExecuteOnce(&lock->once, static_lock_init, lock, NULL)) {
abort();
}
EnterCriticalSection(&lock->lock);
AcquireSRWLockShared(&lock->lock);
}
void CRYPTO_STATIC_MUTEX_lock_write(struct CRYPTO_STATIC_MUTEX *lock) {
CRYPTO_STATIC_MUTEX_lock_read(lock);
AcquireSRWLockExclusive(&lock->lock);
}
void CRYPTO_STATIC_MUTEX_unlock_read(struct CRYPTO_STATIC_MUTEX *lock) {
LeaveCriticalSection(&lock->lock);
ReleaseSRWLockShared(&lock->lock);
}
void CRYPTO_STATIC_MUTEX_unlock_write(struct CRYPTO_STATIC_MUTEX *lock) {
LeaveCriticalSection(&lock->lock);
ReleaseSRWLockExclusive(&lock->lock);
}
static CRITICAL_SECTION g_destructors_lock;

View File

@ -73,10 +73,9 @@ typedef struct crypto_mutex_st {
#elif defined(OPENSSL_WINDOWS)
/* CRYPTO_MUTEX can appear in public header files so we really don't want to
* pull in windows.h. It's statically asserted that this structure is large
* enough to contain a Windows CRITICAL_SECTION by thread_win.c. */
* enough to contain a Windows SRWLOCK by thread_win.c. */
typedef union crypto_mutex_st {
double alignment;
uint8_t padding[4*sizeof(void*) + 2*sizeof(int)];
void *handle;
} CRYPTO_MUTEX;
#elif defined(__MACH__) && defined(__APPLE__)
typedef pthread_rwlock_t CRYPTO_MUTEX;