From 90078aa018ca13cf80d7ccaaa15a8360631b5110 Mon Sep 17 00:00:00 2001 From: Dmitry Kostjuchenko Date: Tue, 22 Nov 2016 18:37:43 +0200 Subject: Compile fix on platforms with missing pthread_rwlock_t. Fix compilation on platforms with missing pthread_rwlock_t implementation by replacing it with pthread_mutex_t. An example of such platform can be Android OS 2.0 - 2.1, API level 5 (Eclair), Android NDK platform - android-5 where pthread_rwlock_t is not implemented and is missing in pthread.h. In case of missing pthread_rwlock_t implementation CRYPTO_RWLOCK will work as exclusive lock in write-only mode of pthread_rwlock_t lock. The implementation based on pthread_mutex_t must be using PTHREAD_MUTEX_RECURSIVE mode to be compatible with recursive behavior of pthread_rwlock_rdlock. Reviewed-by: Rich Salz Reviewed-by: Richard Levitte (Merged from https://github.com/openssl/openssl/pull/1981) (cherry picked from commit 2accf3f7e013c3d02312afc27cc2edbd1f149db3) --- crypto/threads_pthread.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'crypto/threads_pthread.c') diff --git a/crypto/threads_pthread.c b/crypto/threads_pthread.c index 5cc48afb16..f10757c5dc 100644 --- a/crypto/threads_pthread.c +++ b/crypto/threads_pthread.c @@ -11,8 +11,13 @@ #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG) && !defined(OPENSSL_SYS_WINDOWS) +#ifdef PTHREAD_RWLOCK_INITIALIZER + #define OPENSSL_THREADS_HAVE_PTHREAD_RWLOCK +#endif + CRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void) { +#ifdef OPENSSL_THREADS_HAVE_PTHREAD_RWLOCK CRYPTO_RWLOCK *lock = OPENSSL_zalloc(sizeof(pthread_rwlock_t)); if (lock == NULL) return NULL; @@ -21,30 +26,62 @@ CRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void) OPENSSL_free(lock); return NULL; } +#else + CRYPTO_RWLOCK *lock = OPENSSL_zalloc(sizeof(pthread_mutex_t)); + if (lock == NULL) + return NULL; + + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + + if (pthread_mutex_init(lock, &attr) != 0) { + pthread_mutexattr_destroy(&attr); + OPENSSL_free(lock); + return NULL; + } + + pthread_mutexattr_destroy(&attr); +#endif return lock; } int CRYPTO_THREAD_read_lock(CRYPTO_RWLOCK *lock) { +#ifdef OPENSSL_THREADS_HAVE_PTHREAD_RWLOCK if (pthread_rwlock_rdlock(lock) != 0) return 0; +#else + if (pthread_mutex_lock(lock) != 0) + return 0; +#endif return 1; } int CRYPTO_THREAD_write_lock(CRYPTO_RWLOCK *lock) { +#ifdef OPENSSL_THREADS_HAVE_PTHREAD_RWLOCK if (pthread_rwlock_wrlock(lock) != 0) return 0; +#else + if (pthread_mutex_lock(lock) != 0) + return 0; +#endif return 1; } int CRYPTO_THREAD_unlock(CRYPTO_RWLOCK *lock) { +#ifdef OPENSSL_THREADS_HAVE_PTHREAD_RWLOCK if (pthread_rwlock_unlock(lock) != 0) return 0; +#else + if (pthread_mutex_unlock(lock) != 0) + return 0; +#endif return 1; } @@ -54,7 +91,11 @@ void CRYPTO_THREAD_lock_free(CRYPTO_RWLOCK *lock) if (lock == NULL) return; +#ifdef OPENSSL_THREADS_HAVE_PTHREAD_RWLOCK pthread_rwlock_destroy(lock); +#else + pthread_mutex_destroy(lock); +#endif OPENSSL_free(lock); return; -- cgit v1.2.3