crypto: add mutexes.
Prior to this, BoringSSL was using OpenSSL's technique of having users
register a callback for locking operation. This change adds native mutex
support.
Since mutexes often need to be in objects that are exposed via public
headers, the non-static mutexes are defined in thread.h. However, on
Windows we don't want to #include windows.h for CRITICAL_SECTION and, on
Linux, pthread.h doesn't define pthread_rwlock_t unless the feature
flags are set correctly—something that we can't control in general
for public header files. Thus, on both platforms, the mutex is defined
as a uint8_t[] of equal or greater size and we depend on static asserts
to ensure that everything works out ok.
Change-Id: Iafec17ae7e3422325e587878a5384107ec6647ab
Reviewed-on: https://boringssl-review.googlesource.com/4321
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/thread_pthread.c b/crypto/thread_pthread.c
index 1516ea1..4188c4c 100644
--- a/crypto/thread_pthread.c
+++ b/crypto/thread_pthread.c
@@ -17,11 +17,62 @@
#if !defined(OPENSSL_WINDOWS)
#include <pthread.h>
+#include <stdlib.h>
#include <string.h>
#include <openssl/mem.h>
+#include <openssl/type_check.h>
+OPENSSL_COMPILE_ASSERT(sizeof(CRYPTO_MUTEX) >= sizeof(pthread_rwlock_t),
+ CRYPTO_MUTEX_too_small);
+
+void CRYPTO_MUTEX_init(CRYPTO_MUTEX *lock) {
+ if (pthread_rwlock_init((pthread_rwlock_t *) lock, NULL) != 0) {
+ abort();
+ }
+}
+
+void CRYPTO_MUTEX_lock_read(CRYPTO_MUTEX *lock) {
+ if (pthread_rwlock_rdlock((pthread_rwlock_t *) lock) != 0) {
+ abort();
+ }
+}
+
+void CRYPTO_MUTEX_lock_write(CRYPTO_MUTEX *lock) {
+ if (pthread_rwlock_wrlock((pthread_rwlock_t *) lock) != 0) {
+ abort();
+ }
+}
+
+void CRYPTO_MUTEX_unlock(CRYPTO_MUTEX *lock) {
+ if (pthread_rwlock_unlock((pthread_rwlock_t *) lock) != 0) {
+ abort();
+ }
+}
+
+void CRYPTO_MUTEX_cleanup(CRYPTO_MUTEX *lock) {
+ pthread_rwlock_destroy((pthread_rwlock_t *) lock);
+}
+
+void CRYPTO_STATIC_MUTEX_lock_read(struct CRYPTO_STATIC_MUTEX *lock) {
+ if (pthread_rwlock_rdlock(&lock->lock) != 0) {
+ abort();
+ }
+}
+
+void CRYPTO_STATIC_MUTEX_lock_write(struct CRYPTO_STATIC_MUTEX *lock) {
+ if (pthread_rwlock_wrlock(&lock->lock) != 0) {
+ abort();
+ }
+}
+
+void CRYPTO_STATIC_MUTEX_unlock(struct CRYPTO_STATIC_MUTEX *lock) {
+ if (pthread_rwlock_unlock(&lock->lock) != 0) {
+ abort();
+ }
+}
+
void CRYPTO_once(CRYPTO_once_t *once, void (*init)(void)) {
pthread_once(once, init);
}