diff --git a/crypto/internal.h b/crypto/internal.h index 2d130fc9..433072ce 100644 --- a/crypto/internal.h +++ b/crypto/internal.h @@ -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 diff --git a/crypto/thread_win.c b/crypto/thread_win.c index 85e59939..9f7d82b3 100644 --- a/crypto/thread_win.c +++ b/crypto/thread_win.c @@ -27,7 +27,7 @@ #include -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; diff --git a/include/openssl/thread.h b/include/openssl/thread.h index ac4ced07..02539e81 100644 --- a/include/openssl/thread.h +++ b/include/openssl/thread.h @@ -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;