Add a CRYPTO_atomic_read call which allows an int variable to be read
authorPauli <paul.dale@oracle.com>
Mon, 25 Sep 2017 02:04:42 +0000 (12:04 +1000)
committerPauli <paul.dale@oracle.com>
Mon, 9 Oct 2017 22:45:52 +0000 (08:45 +1000)
in an atomic fashion.

Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/4414)

crypto/threads_none.c
crypto/threads_pthread.c
crypto/threads_win.c
doc/man3/CRYPTO_THREAD_run_once.pod
include/openssl/crypto.h
util/libcrypto.num

index ffad7576b171000b4802f5cdc9642cf7d2a75330..7e9ec2d15148eb9636fe0e899120fce653afa600 100644 (file)
@@ -125,6 +125,12 @@ int CRYPTO_atomic_add(int *val, int amount, int *ret, CRYPTO_RWLOCK *lock)
     return 1;
 }
 
+int CRYPTO_atomic_read(int *val, int *ret, CRYPTO_RWLOCK *lock)
+{
+    *ret  = *val;
+    return 1;
+}
+
 int openssl_init_fork_handlers(void)
 {
     return 0;
index 9644c25aea947acbfba6ef7f8bc71601d4e3be9d..3f8ada2c370c4843bce53ef0208fb0dfc4a1d0a4 100644 (file)
@@ -169,6 +169,25 @@ int CRYPTO_atomic_add(int *val, int amount, int *ret, CRYPTO_RWLOCK *lock)
     return 1;
 }
 
+int CRYPTO_atomic_read(int *val, int *ret, CRYPTO_RWLOCK *lock)
+{
+# if defined(__GNUC__) && defined(__ATOMIC_ACQUIRE)
+    if (__atomic_is_lock_free(sizeof(*val), val)) {
+        __atomic_load(val, ret, __ATOMIC_ACQUIRE);
+        return 1;
+    }
+# endif
+    if (!CRYPTO_THREAD_write_lock(lock))
+        return 0;
+
+    *ret  = *val;
+
+    if (!CRYPTO_THREAD_unlock(lock))
+        return 0;
+
+    return 1;
+}
+
 # ifdef OPENSSL_SYS_UNIX
 static pthread_once_t fork_once_control = PTHREAD_ONCE_INIT;
 
index 512e19f5f3f01d9ab2e2171ebc33ab3b143bd06b..6f9c7b1bd398cb08ea791b2047d13bc135d34fb2 100644 (file)
@@ -133,6 +133,12 @@ int CRYPTO_atomic_add(int *val, int amount, int *ret, CRYPTO_RWLOCK *lock)
     return 1;
 }
 
+int CRYPTO_atomic_read(int *val, int *ret, CRYPTO_RWLOCK *lock)
+{
+    InterlockedCompareExchange(val, 0, 0);
+    return 1;
+}
+
 int openssl_init_fork_handlers(void)
 {
     return 0;
index 9a4df1992c0e7b3cfbd835b6bd22bca8a28d3926..bf4a2f2cefa6fe0acdadfc74011e15e299e55b3b 100644 (file)
@@ -4,7 +4,8 @@
 
 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 - OpenSSL thread support
+CRYPTO_THREAD_unlock, CRYPTO_THREAD_lock_free, CRYPTO_atomic_add,
+CRYPTO_atomic_read - OpenSSL thread support
 
 =head1 SYNOPSIS
 
@@ -20,6 +21,7 @@ CRYPTO_THREAD_unlock, CRYPTO_THREAD_lock_free, CRYPTO_atomic_add - OpenSSL threa
  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);
 
 =head1 DESCRIPTION
 
@@ -74,6 +76,12 @@ operations are supported on the specific platform. Because of this, if a
 variable is modified by CRYPTO_atomic_add() then CRYPTO_atomic_add() must
 be the only way that the variable is modified.
 
+=item *
+
+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.
+
 =back
 
 =head1 RETURN VALUES
index 9fc0663233556fbd7d706dc54d2b10cf0a475a86..a9f080d53ccc420686ccff66d19dab32cfc19219 100644 (file)
@@ -74,6 +74,7 @@ int CRYPTO_THREAD_unlock(CRYPTO_RWLOCK *lock);
 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);
 
 /*
  * The following can be used to detect memory leaks in the library. If
index 48e97ff135e397e1bce3f614e0c0a40d99a50d07..68f89b63020bc059872d0fc61704281f47171cab 100644 (file)
@@ -4398,3 +4398,4 @@ EVP_PKEY_meth_set_check                 4341      1_1_1   EXIST::FUNCTION:
 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: