From: Pauli Date: Mon, 9 Oct 2017 04:39:43 +0000 (+1000) Subject: Add atomic write call X-Git-Tag: OpenSSL_1_1_1-pre1~582 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=30ff41beab5d8a53cbcbdab4109b32b9ef5c0f6e;p=oweals%2Fopenssl.git Add atomic write call Reviewed-by: Rich Salz (Merged from https://github.com/openssl/openssl/pull/4414) --- diff --git a/crypto/threads_none.c b/crypto/threads_none.c index 7e9ec2d151..30ed4e6999 100644 --- a/crypto/threads_none.c +++ b/crypto/threads_none.c @@ -127,7 +127,13 @@ int CRYPTO_atomic_add(int *val, int amount, int *ret, CRYPTO_RWLOCK *lock) int CRYPTO_atomic_read(int *val, int *ret, CRYPTO_RWLOCK *lock) { - *ret = *val; + *ret = *val; + return 1; +} + +int CRYPTO_atomic_write(int *val, int n, CRYPTO_RWLOCK *lock) +{ + *val = n; return 1; } diff --git a/crypto/threads_pthread.c b/crypto/threads_pthread.c index 3f8ada2c37..34be314f1f 100644 --- a/crypto/threads_pthread.c +++ b/crypto/threads_pthread.c @@ -188,6 +188,25 @@ int CRYPTO_atomic_read(int *val, int *ret, CRYPTO_RWLOCK *lock) return 1; } +int CRYPTO_atomic_write(int *val, int n, CRYPTO_RWLOCK *lock) +{ +# if defined(__GNUC__) && defined(__ATOMIC_RELEASE) + if (__atomic_is_lock_free(sizeof(*val), val)) { + __atomic_store(val, &n, __ATOMIC_RELEASE); + return 1; + } +# endif + if (!CRYPTO_THREAD_write_lock(lock)) + return 0; + + *val = n; + + if (!CRYPTO_THREAD_unlock(lock)) + return 0; + + return 1; +} + # ifdef OPENSSL_SYS_UNIX static pthread_once_t fork_once_control = PTHREAD_ONCE_INIT; diff --git a/crypto/threads_win.c b/crypto/threads_win.c index 6f9c7b1bd3..ab2eb25740 100644 --- a/crypto/threads_win.c +++ b/crypto/threads_win.c @@ -139,6 +139,12 @@ int CRYPTO_atomic_read(int *val, int *ret, CRYPTO_RWLOCK *lock) return 1; } +int CRYPTO_atomic_write(int *val, int n, CRYPTO_RWLOCK *lock) +{ + InterlockedExchange(val, n); + return 1; +} + int openssl_init_fork_handlers(void) { return 0; diff --git a/doc/man3/CRYPTO_THREAD_run_once.pod b/doc/man3/CRYPTO_THREAD_run_once.pod index bf4a2f2cef..734d2d8874 100644 --- a/doc/man3/CRYPTO_THREAD_run_once.pod +++ b/doc/man3/CRYPTO_THREAD_run_once.pod @@ -5,7 +5,7 @@ CRYPTO_THREAD_run_once, CRYPTO_THREAD_lock_new, CRYPTO_THREAD_read_lock, CRYPTO_THREAD_write_lock, CRYPTO_THREAD_unlock, CRYPTO_THREAD_lock_free, CRYPTO_atomic_add, -CRYPTO_atomic_read - OpenSSL thread support +CRYPTO_atomic_read, CRYPTO_atomic_write - OpenSSL thread support =head1 SYNOPSIS @@ -22,6 +22,7 @@ CRYPTO_atomic_read - OpenSSL thread support int CRYPTO_atomic_add(int *val, int amount, int *ret, CRYPTO_RWLOCK *lock); int CRYPTO_atomic_read(int *val, int *ret, CRYPTO_RWLOCK *lock); + int CRYPTO_atomic_write(int *val, int n, CRYPTO_RWLOCK *lock); =head1 DESCRIPTION @@ -82,6 +83,11 @@ CRYPTO_atomic_read() atomically reads B and returns the result of the operation in B. B will be locked, unless atomic operations are supported on the specific platform. +=item * + +CRYPTO_atomic_write() atomically writes B to B. B will be +locked, unless atomic operations are supported on the specific platform. + =back =head1 RETURN VALUES diff --git a/include/openssl/crypto.h b/include/openssl/crypto.h index a9f080d53c..c2aa07c98d 100644 --- a/include/openssl/crypto.h +++ b/include/openssl/crypto.h @@ -75,6 +75,7 @@ void CRYPTO_THREAD_lock_free(CRYPTO_RWLOCK *lock); int CRYPTO_atomic_add(int *val, int amount, int *ret, CRYPTO_RWLOCK *lock); int CRYPTO_atomic_read(int *val, int *ret, CRYPTO_RWLOCK *lock); +int CRYPTO_atomic_write(int *val, int n, CRYPTO_RWLOCK *lock); /* * The following can be used to detect memory leaks in the library. If diff --git a/util/libcrypto.num b/util/libcrypto.num index 68f89b6302..5343aeddb7 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -4399,3 +4399,4 @@ EVP_PKEY_meth_get_check 4342 1_1_1 EXIST::FUNCTION: EVP_PKEY_meth_remove 4343 1_1_1 EXIST::FUNCTION: OPENSSL_sk_reserve 4344 1_1_1 EXIST::FUNCTION: CRYPTO_atomic_read 4345 1_1_1 EXIST::FUNCTION: +CRYPTO_atomic_write 4346 1_1_1 EXIST::FUNCTION: