Ver Fonte

Add atomic write call

Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/4414)
Pauli há 6 anos atrás
pai
commit
30ff41beab

+ 7 - 1
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;
 }
 

+ 19 - 0
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;
 

+ 6 - 0
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;

+ 7 - 1
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

+ 1 - 0
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

+ 1 - 0
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: