From 5c4328f04f63bc288d4e069e1453ab18b0309f16 Mon Sep 17 00:00:00 2001 From: Viktor Dukhovni Date: Sun, 15 May 2016 13:02:17 -0400 Subject: [PATCH] Fold threads.h into crypto.h making API public Document thread-safe lock creation Reviewed-by: Richard Levitte --- crypto/async/async.c | 1 - crypto/bio/b_addr.c | 2 +- crypto/bn/bn_blind.c | 1 - crypto/engine/eng_int.h | 1 - crypto/err/err.c | 1 - crypto/err/err_prn.c | 1 - crypto/ex_data.c | 1 - crypto/init.c | 1 - crypto/mem_dbg.c | 1 - crypto/mem_sec.c | 1 - crypto/rand/md_rand.c | 1 - crypto/threads_none.c | 1 - crypto/threads_pthread.c | 1 - crypto/threads_win.c | 1 - crypto/x509/by_dir.c | 1 - doc/crypto/threads.pod | 61 ++++++++++++++++++++++++- include/internal/threads.h | 92 -------------------------------------- include/openssl/crypto.h | 38 ++++++++++++++++ ssl/ssl_cert.c | 2 +- ssl/ssl_ciph.c | 2 +- ssl/ssl_init.c | 1 - test/ssltest_old.c | 1 - test/threadstest.c | 1 - util/mkdef.pl | 1 - 24 files changed, 101 insertions(+), 114 deletions(-) delete mode 100644 include/internal/threads.h diff --git a/crypto/async/async.c b/crypto/async/async.c index b4ba561888..719379e175 100644 --- a/crypto/async/async.c +++ b/crypto/async/async.c @@ -61,7 +61,6 @@ /* This must be the first #include file */ #include "async_locl.h" -#include #include #include #include diff --git a/crypto/bio/b_addr.c b/crypto/bio/b_addr.c index 1813f5a9bb..356ab11330 100644 --- a/crypto/bio/b_addr.c +++ b/crypto/bio/b_addr.c @@ -55,7 +55,7 @@ #include #include "bio_lcl.h" -#include "internal/threads.h" +#include #ifndef OPENSSL_NO_SOCK #include diff --git a/crypto/bn/bn_blind.c b/crypto/bn/bn_blind.c index 81b895ce37..fcc4db5205 100644 --- a/crypto/bn/bn_blind.c +++ b/crypto/bn/bn_blind.c @@ -110,7 +110,6 @@ #include #include "internal/cryptlib.h" -#include "internal/threads.h" #include "bn_lcl.h" #define BN_BLINDING_COUNTER 32 diff --git a/crypto/engine/eng_int.h b/crypto/engine/eng_int.h index b1752957db..36bc933695 100644 --- a/crypto/engine/eng_int.h +++ b/crypto/engine/eng_int.h @@ -65,7 +65,6 @@ # define HEADER_ENGINE_INT_H # include "internal/cryptlib.h" -# include "internal/threads.h" # include #ifdef __cplusplus diff --git a/crypto/err/err.c b/crypto/err/err.c index fd2ea8194a..f1a80c0d50 100644 --- a/crypto/err/err.c +++ b/crypto/err/err.c @@ -112,7 +112,6 @@ #include #include #include -#include #include #include #include diff --git a/crypto/err/err_prn.c b/crypto/err/err_prn.c index 0f7d40c398..1cbec54734 100644 --- a/crypto/err/err_prn.c +++ b/crypto/err/err_prn.c @@ -57,7 +57,6 @@ #include #include "internal/cryptlib.h" -#include "internal/threads.h" #include #include #include diff --git a/crypto/ex_data.c b/crypto/ex_data.c index ca1c204f38..2570736304 100644 --- a/crypto/ex_data.c +++ b/crypto/ex_data.c @@ -109,7 +109,6 @@ */ #include "internal/cryptlib_int.h" -#include "internal/threads.h" #include /* diff --git a/crypto/init.c b/crypto/init.c index 938bf78a39..90ab6dff40 100644 --- a/crypto/init.c +++ b/crypto/init.c @@ -55,7 +55,6 @@ * */ -#include #include #include #include diff --git a/crypto/mem_dbg.c b/crypto/mem_dbg.c index 2b8cf73028..0df050d057 100644 --- a/crypto/mem_dbg.c +++ b/crypto/mem_dbg.c @@ -112,7 +112,6 @@ #include #include #include "internal/cryptlib.h" -#include "internal/threads.h" #include #include #include "internal/bio.h" diff --git a/crypto/mem_sec.c b/crypto/mem_sec.c index d61d945d63..31fcee6877 100644 --- a/crypto/mem_sec.c +++ b/crypto/mem_sec.c @@ -25,7 +25,6 @@ # include # include # include -# include "internal/threads.h" #endif #define CLEAR(p, s) OPENSSL_cleanse(p, s) diff --git a/crypto/rand/md_rand.c b/crypto/rand/md_rand.c index e9574b08b8..74beda8bb4 100644 --- a/crypto/rand/md_rand.c +++ b/crypto/rand/md_rand.c @@ -125,7 +125,6 @@ #include #include #include "rand_lcl.h" -#include "internal/threads.h" #include diff --git a/crypto/threads_none.c b/crypto/threads_none.c index 4e3b7a52e8..bd92b8294d 100644 --- a/crypto/threads_none.c +++ b/crypto/threads_none.c @@ -48,7 +48,6 @@ */ #include -#include "internal/threads.h" #if !defined(OPENSSL_THREADS) || defined(CRYPTO_TDEBUG) diff --git a/crypto/threads_pthread.c b/crypto/threads_pthread.c index edca77c0b9..c861faa9bd 100644 --- a/crypto/threads_pthread.c +++ b/crypto/threads_pthread.c @@ -48,7 +48,6 @@ */ #include -#include "internal/threads.h" #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG) && !defined(OPENSSL_SYS_WINDOWS) diff --git a/crypto/threads_win.c b/crypto/threads_win.c index 63647a39a6..f2c4cfa179 100644 --- a/crypto/threads_win.c +++ b/crypto/threads_win.c @@ -48,7 +48,6 @@ */ #include -#include "internal/threads.h" #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG) && defined(OPENSSL_SYS_WINDOWS) diff --git a/crypto/x509/by_dir.c b/crypto/x509/by_dir.c index 55241175b5..9b3f4f50cb 100644 --- a/crypto/x509/by_dir.c +++ b/crypto/x509/by_dir.c @@ -71,7 +71,6 @@ #include #include -#include "internal/threads.h" #include "internal/x509_int.h" #include "x509_lcl.h" diff --git a/doc/crypto/threads.pod b/doc/crypto/threads.pod index 90c57098a4..bb21462f3e 100644 --- a/doc/crypto/threads.pod +++ b/doc/crypto/threads.pod @@ -2,6 +2,7 @@ =head1 NAME +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 @@ -9,6 +10,9 @@ CRYPTO_THREAD_unlock, CRYPTO_THREAD_lock_free, CRYPTO_atomic_add - OpenSSL threa #include + CRYPTO_ONCE CRYPTO_ONCE_STATIC_INIT; + int CRYPTO_THREAD_run_once(CRYPTO_ONCE *once, void (*init)(void)); + CRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void); int CRYPTO_THREAD_read_lock(CRYPTO_RWLOCK *lock); int CRYPTO_THREAD_write_lock(CRYPTO_RWLOCK *lock); @@ -30,6 +34,16 @@ The following multi-threading function are provided: =over 4 +=item * +CRYPTO_THREAD_run_once() can be used to perform one-time initialization. +The B argument must be a pointer to a static object of type +B that was statically initialized to the value +B. +The B argument is a pointer to a function that performs the desired +exactly once initialization. +In particular, this can be used to allocate locks in a thread-safe manner, +which can then be used with the locking functions below. + =item * CRYPTO_THREAD_lock_new() allocates, initializes and returns a new read/write lock. @@ -57,17 +71,62 @@ be the only way that the variable is modified. =head1 RETURN VALUES +CRYPTO_THREAD_run_once() returns 1 on success, or 0 on error. + CRYPTO_THREAD_lock_new() returns the allocated lock, or NULL on error. CRYPTO_THREAD_lock_frees() returns no value. The other functions return 1 on success or 0 on error. +=head1 EXAMPLE + +This example safely initializes and uses a lock. + + #include + + static CRYPTO_ONCE once = CRYPTO_ONCE_STATIC_INIT; + static CRYPTO_RWLOCK *lock; + + static void myinit(void) + { + lock = CRYPTO_THREAD_lock_new(); + } + + static int mylock(void) + { + if (!CRYPTO_THREAD_run_once(&once, void init) || lock == NULL) + return 0; + return CRYPTO_THREAD_write_lock(lock); + } + + static int myunlock(void) + { + return CRYPTO_THREAD_unlock(lock); + } + + int serialized(void) + { + int ret = 0; + + if (mylock()) { + /* Your code here, do not return without releasing the lock! */ + ret = ... ; + } + myunlock(); + return ret; + } + +Finalization of locks is an advanced topic, not covered in this example. +This can only be done at process exit or when a dynamically loaded library is +no longer in use and is unloaded. +The simplest solution is to just "leak" the lock in applications and not +repeatedly load/unload shared libraries that allocate locks. + =head1 NOTES You can find out if OpenSSL was configured with thread support: - #define OPENSSL_THREAD_DEFINES #include #if defined(OPENSSL_THREADS) // thread support enabled diff --git a/include/internal/threads.h b/include/internal/threads.h deleted file mode 100644 index 78977281d7..0000000000 --- a/include/internal/threads.h +++ /dev/null @@ -1,92 +0,0 @@ -/* ==================================================================== - * Copyright (c) 2016 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef HEADER_INTERNAL_THREADS_H -# define HEADER_INTERNAL_THREADS_H - -#include "e_os.h" - -# if !defined(OPENSSL_THREADS) || defined(CRYPTO_TDEBUG) -typedef unsigned int CRYPTO_ONCE; -typedef unsigned int CRYPTO_THREAD_LOCAL; -typedef unsigned int CRYPTO_THREAD_ID; - -# define CRYPTO_ONCE_STATIC_INIT 0 -# elif defined(OPENSSL_SYS_WINDOWS) -# include -typedef DWORD CRYPTO_THREAD_LOCAL; -typedef DWORD CRYPTO_THREAD_ID; - -# if _WIN32_WINNT < 0x0600 -typedef LONG CRYPTO_ONCE; -# define CRYPTO_ONCE_STATIC_INIT 0 -# else -typedef INIT_ONCE CRYPTO_ONCE; -# define CRYPTO_ONCE_STATIC_INIT INIT_ONCE_STATIC_INIT -# endif - -# else -# include -typedef pthread_once_t CRYPTO_ONCE; -typedef pthread_key_t CRYPTO_THREAD_LOCAL; -typedef pthread_t CRYPTO_THREAD_ID; - -# define CRYPTO_ONCE_STATIC_INIT PTHREAD_ONCE_INIT -# endif - -int CRYPTO_THREAD_run_once(CRYPTO_ONCE *once, void (*init)(void)); - -int CRYPTO_THREAD_init_local(CRYPTO_THREAD_LOCAL *key, void (*cleanup)(void *)); -void *CRYPTO_THREAD_get_local(CRYPTO_THREAD_LOCAL *key); -int CRYPTO_THREAD_set_local(CRYPTO_THREAD_LOCAL *key, void *val); -int CRYPTO_THREAD_cleanup_local(CRYPTO_THREAD_LOCAL *key); - -CRYPTO_THREAD_ID CRYPTO_THREAD_get_current_id(void); -int CRYPTO_THREAD_compare_id(CRYPTO_THREAD_ID a, CRYPTO_THREAD_ID b); - -#endif diff --git a/include/openssl/crypto.h b/include/openssl/crypto.h index 5e16318d7b..3d73c62f29 100644 --- a/include/openssl/crypto.h +++ b/include/openssl/crypto.h @@ -485,6 +485,44 @@ void OPENSSL_INIT_set_config_filename(OPENSSL_INIT_SETTINGS *settings, #endif void OPENSSL_INIT_free(OPENSSL_INIT_SETTINGS *settings); +# if !defined(OPENSSL_THREADS) || defined(CRYPTO_TDEBUG) +typedef unsigned int CRYPTO_ONCE; +typedef unsigned int CRYPTO_THREAD_LOCAL; +typedef unsigned int CRYPTO_THREAD_ID; + +# define CRYPTO_ONCE_STATIC_INIT 0 +# elif defined(OPENSSL_SYS_WINDOWS) +# include +typedef DWORD CRYPTO_THREAD_LOCAL; +typedef DWORD CRYPTO_THREAD_ID; + +# if _WIN32_WINNT < 0x0600 +typedef LONG CRYPTO_ONCE; +# define CRYPTO_ONCE_STATIC_INIT 0 +# else +typedef INIT_ONCE CRYPTO_ONCE; +# define CRYPTO_ONCE_STATIC_INIT INIT_ONCE_STATIC_INIT +# endif + +# else +# include +typedef pthread_once_t CRYPTO_ONCE; +typedef pthread_key_t CRYPTO_THREAD_LOCAL; +typedef pthread_t CRYPTO_THREAD_ID; + +# define CRYPTO_ONCE_STATIC_INIT PTHREAD_ONCE_INIT +# endif + +int CRYPTO_THREAD_run_once(CRYPTO_ONCE *once, void (*init)(void)); + +int CRYPTO_THREAD_init_local(CRYPTO_THREAD_LOCAL *key, void (*cleanup)(void *)); +void *CRYPTO_THREAD_get_local(CRYPTO_THREAD_LOCAL *key); +int CRYPTO_THREAD_set_local(CRYPTO_THREAD_LOCAL *key, void *val); +int CRYPTO_THREAD_cleanup_local(CRYPTO_THREAD_LOCAL *key); + +CRYPTO_THREAD_ID CRYPTO_THREAD_get_current_id(void); +int CRYPTO_THREAD_compare_id(CRYPTO_THREAD_ID a, CRYPTO_THREAD_ID b); + /* BEGIN ERROR CODES */ /* * The following lines are auto generated by the script mkerr.pl. Any changes diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c index dc7debbab2..43589ef271 100644 --- a/ssl/ssl_cert.c +++ b/ssl/ssl_cert.c @@ -127,7 +127,7 @@ #include #include #include -#include "internal/threads.h" +#include #include "ssl_locl.h" static int ssl_security_default_callback(const SSL *s, const SSL_CTX *ctx, int op, diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c index 8b65daa95c..435deb8fae 100644 --- a/ssl/ssl_ciph.c +++ b/ssl/ssl_ciph.c @@ -144,7 +144,7 @@ #include #include #include -#include "internal/threads.h" +#include #include "ssl_locl.h" #define SSL_ENC_DES_IDX 0 diff --git a/ssl/ssl_init.c b/ssl/ssl_init.c index 546f5d23a8..9ed06fb4a2 100644 --- a/ssl/ssl_init.c +++ b/ssl/ssl_init.c @@ -57,7 +57,6 @@ #include "e_os.h" -#include "internal/threads.h" #include "internal/err.h" #include #include diff --git a/test/ssltest_old.c b/test/ssltest_old.c index eb35c1d6c0..14d5b71dda 100644 --- a/test/ssltest_old.c +++ b/test/ssltest_old.c @@ -191,7 +191,6 @@ # include #endif -#include "internal/threads.h" #include "../ssl/ssl_locl.h" /* diff --git a/test/threadstest.c b/test/threadstest.c index e3a9ff5849..e15f2c31ae 100644 --- a/test/threadstest.c +++ b/test/threadstest.c @@ -50,7 +50,6 @@ #include #include -#include "internal/threads.h" #if !defined(OPENSSL_THREADS) || defined(CRYPTO_TDEBUG) diff --git a/util/mkdef.pl b/util/mkdef.pl index 4d8befe19f..c2fbfe7062 100755 --- a/util/mkdef.pl +++ b/util/mkdef.pl @@ -247,7 +247,6 @@ $ssl.=" include/openssl/srtp.h"; my $crypto ="include/openssl/crypto.h"; $crypto.=" include/internal/o_dir.h"; $crypto.=" include/internal/o_str.h"; -$crypto.=" include/internal/threads.h"; $crypto.=" include/internal/err.h"; $crypto.=" include/openssl/des.h" ; # unless $no_des; $crypto.=" include/openssl/idea.h" ; # unless $no_idea; -- 2.25.1