summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crypto/threads_none.c8
-rw-r--r--crypto/threads_pthread.c19
-rw-r--r--crypto/threads_win.c6
-rw-r--r--doc/man3/CRYPTO_THREAD_run_once.pod8
-rw-r--r--include/openssl/crypto.h1
-rw-r--r--util/libcrypto.num1
6 files changed, 41 insertions, 2 deletions
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<val> and returns the result of
the operation in B<ret>. B<lock> will be locked, unless atomic operations
are supported on the specific platform.
+=item *
+
+CRYPTO_atomic_write() atomically writes B<n> to B<val>. B<lock> 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: