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>
diff --git a/crypto/internal.h b/crypto/internal.h
index 2d130fc..433072c 100644
--- a/crypto/internal.h
+++ b/crypto/internal.h
@@ -355,12 +355,8 @@
* |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 @@
#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 @@
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 85e5993..9f7d82b 100644
--- a/crypto/thread_win.c
+++ b/crypto/thread_win.c
@@ -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_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 ac4ced0..02539e8 100644
--- a/include/openssl/thread.h
+++ b/include/openssl/thread.h
@@ -73,10 +73,9 @@
#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;