diff options
author | Matt Caswell <matt@openssl.org> | 2016-03-02 14:51:00 +0000 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2016-03-07 17:17:21 +0000 |
commit | b1f1e7aebad6ece6d878ca7e823b4ad92e2415f3 (patch) | |
tree | 394f4cde5fcd3d887bf8d20cdd92fc6fe39fae23 /ssl/ssl_init.c | |
parent | 48fe8ab02e7080a5557e287a5190cbbd40021a98 (diff) | |
download | openssl-b1f1e7aebad6ece6d878ca7e823b4ad92e2415f3.tar.gz |
Swap the init code to use CRYPTO_ONCE
The init code was using its own "once" implementation. Now that we have
the new thread API we should use that instead.
Reviewed-by: Richard Levitte <levitte@openssl.org>
Diffstat (limited to 'ssl/ssl_init.c')
-rw-r--r-- | ssl/ssl_init.c | 97 |
1 files changed, 13 insertions, 84 deletions
diff --git a/ssl/ssl_init.c b/ssl/ssl_init.c index 7d89ed0a60..413fa4105b 100644 --- a/ssl/ssl_init.c +++ b/ssl/ssl_init.c @@ -57,6 +57,7 @@ #include "e_os.h" +#include <internal/threads.h> #include <openssl/crypto.h> #include <openssl/evp.h> #include <assert.h> @@ -64,86 +65,9 @@ static int stopped; -/* Implement "once" functionality */ -#if !defined(OPENSSL_THREADS) -typedef int OPENSSL_INIT_ONCE; -# define OPENSSL_INIT_ONCE_STATIC_INIT 0 - -static void ossl_init_once_run(OPENSSL_INIT_ONCE *once, void (*init)(void)) -{ - if (*once == OPENSSL_INIT_ONCE_STATIC_INIT) { - *once = 1; - init(); - } -} -#elif defined(OPENSSL_SYS_WINDOWS) -# include <windows.h> - -# if _WIN32_WINNT < 0x0600 - -/* - * Versions before 0x0600 (Windows Vista, Windows Server 2008 or later) do not - * have InitOnceExecuteOnce, so we fall back to using a spinlock instead. - */ -typedef LONG OPENSSL_INIT_ONCE; -# define OPENSSL_INIT_ONCE_STATIC_INIT 0 - -# define ONCE_UNINITED 0 -# define ONCE_ININIT 1 -# define ONCE_DONE 2 - -static void ossl_init_once_run(OPENSSL_INIT_ONCE *once, void (*init)(void)) -{ - LONG volatile *lock = (LONG *)once; - LONG result; - - if (*lock == ONCE_DONE) - return; - - do { - result = InterlockedCompareExchange(lock, ONCE_ININIT, ONCE_UNINITED); - if (result == ONCE_UNINITED) { - init(); - *lock = ONCE_DONE; - return; - } - } while (result == ONCE_ININIT); -} - -# else - -typedef INIT_ONCE OPENSSL_INIT_ONCE; -# define OPENSSL_INIT_ONCE_STATIC_INIT INIT_ONCE_STATIC_INIT - -static BOOL CALLBACK once_cb(PINIT_ONCE once, PVOID initfp, PVOID *unused) -{ - void (*init)(void) = initfp; - - init(); - - return TRUE; -} - -static void ossl_init_once_run(OPENSSL_INIT_ONCE *once, void (*init)(void)) -{ - InitOnceExecuteOnce((INIT_ONCE *)once, once_cb, init, NULL); -} -# endif -#else /* pthreads */ -# include <pthread.h> - -typedef pthread_once_t OPENSSL_INIT_ONCE; -# define OPENSSL_INIT_ONCE_STATIC_INIT PTHREAD_ONCE_INIT - -static void ossl_init_once_run(OPENSSL_INIT_ONCE *once, void (*init)(void)) -{ - pthread_once(once, init); -} -#endif - static void ssl_library_stop(void); -static OPENSSL_INIT_ONCE ssl_base = OPENSSL_INIT_ONCE_STATIC_INIT; +static CRYPTO_ONCE ssl_base = CRYPTO_ONCE_STATIC_INIT; static int ssl_base_inited = 0; static void ossl_init_ssl_base(void) { @@ -238,7 +162,7 @@ static void ossl_init_ssl_base(void) ssl_base_inited = 1; } -static OPENSSL_INIT_ONCE ssl_strings = OPENSSL_INIT_ONCE_STATIC_INIT; +static CRYPTO_ONCE ssl_strings = CRYPTO_ONCE_STATIC_INIT; static int ssl_strings_inited = 0; static void ossl_init_load_ssl_strings(void) { @@ -321,13 +245,18 @@ int OPENSSL_init_ssl(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings) | OPENSSL_INIT_ADD_ALL_DIGESTS, settings)) return 0; - ossl_init_once_run(&ssl_base, ossl_init_ssl_base); + if (!CRYPTO_THREAD_run_once(&ssl_base, ossl_init_ssl_base)) + return 0; - if (opts & OPENSSL_INIT_NO_LOAD_SSL_STRINGS) - ossl_init_once_run(&ssl_strings, ossl_init_no_load_ssl_strings); + if ((opts & OPENSSL_INIT_NO_LOAD_SSL_STRINGS) + && !CRYPTO_THREAD_run_once(&ssl_strings, + ossl_init_no_load_ssl_strings)) + return 0; - if (opts & OPENSSL_INIT_LOAD_SSL_STRINGS) - ossl_init_once_run(&ssl_strings, ossl_init_load_ssl_strings); + if ((opts & OPENSSL_INIT_LOAD_SSL_STRINGS) + && !CRYPTO_THREAD_run_once(&ssl_strings, + ossl_init_load_ssl_strings)) + return 0; return 1; } |