/*
* Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
#include <openssl/crypto.h>
#include "internal/cryptlib.h"
+#if defined(__sun)
+# include <atomic.h>
+#endif
+
#if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG) && !defined(OPENSSL_SYS_WINDOWS)
+# if defined(OPENSSL_SYS_UNIX)
+# include <sys/types.h>
+# include <unistd.h>
+#endif
+
# ifdef PTHREAD_RWLOCK_INITIALIZER
# define USE_RWLOCK
# endif
*ret = __atomic_add_fetch(val, amount, __ATOMIC_ACQ_REL);
return 1;
}
-# endif
- if (!CRYPTO_THREAD_write_lock(lock))
- return 0;
-
- *val += amount;
- *ret = *val;
-
- if (!CRYPTO_THREAD_unlock(lock))
- return 0;
-
- 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);
+# elif defined(__sun) && (defined(__SunOS_5_10) || defined(__SunOS_5_11))
+ /* This will work for all future Solaris versions. */
+ if (ret != NULL) {
+ *ret = atomic_add_int_nv((volatile unsigned int *)val, amount);
return 1;
}
# endif
- if (!CRYPTO_THREAD_read_lock(lock))
+ if (!CRYPTO_THREAD_write_lock(lock))
return 0;
+ *val += amount;
*ret = *val;
if (!CRYPTO_THREAD_unlock(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;
-}
+# ifndef FIPS_MODE
+/* TODO(3.0): No fork protection in FIPS module yet! */
-# ifdef OPENSSL_SYS_UNIX
+# ifdef OPENSSL_SYS_UNIX
static pthread_once_t fork_once_control = PTHREAD_ONCE_INIT;
static void fork_once_func(void)
pthread_atfork(OPENSSL_fork_prepare,
OPENSSL_fork_parent, OPENSSL_fork_child);
}
-# endif
+# endif
int openssl_init_fork_handlers(void)
{
-# ifdef OPENSSL_SYS_UNIX
+# ifdef OPENSSL_SYS_UNIX
if (pthread_once(&fork_once_control, fork_once_func) == 0)
return 1;
-# endif
+# endif
return 0;
}
+# endif /* FIPS_MODE */
+
+int openssl_get_fork_id(void)
+{
+ return getpid();
+}
#endif