1=pod 2 3=head1 NAME 4 5CRYPTO_THREAD_run_once, 6CRYPTO_THREAD_lock_new, CRYPTO_THREAD_read_lock, CRYPTO_THREAD_write_lock, 7CRYPTO_THREAD_unlock, CRYPTO_THREAD_lock_free, 8CRYPTO_atomic_add, CRYPTO_atomic_add64, CRYPTO_atomic_and, CRYPTO_atomic_or, 9CRYPTO_atomic_load, CRYPTO_atomic_store, CRYPTO_atomic_load_int, 10OSSL_set_max_threads, OSSL_get_max_threads, 11OSSL_get_thread_support_flags, OSSL_THREAD_SUPPORT_FLAG_THREAD_POOL, 12OSSL_THREAD_SUPPORT_FLAG_DEFAULT_SPAWN - OpenSSL thread support 13 14=head1 SYNOPSIS 15 16 #include <openssl/crypto.h> 17 18 CRYPTO_ONCE CRYPTO_ONCE_STATIC_INIT; 19 int CRYPTO_THREAD_run_once(CRYPTO_ONCE *once, void (*init)(void)); 20 21 CRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void); 22 int CRYPTO_THREAD_read_lock(CRYPTO_RWLOCK *lock); 23 int CRYPTO_THREAD_write_lock(CRYPTO_RWLOCK *lock); 24 int CRYPTO_THREAD_unlock(CRYPTO_RWLOCK *lock); 25 void CRYPTO_THREAD_lock_free(CRYPTO_RWLOCK *lock); 26 27 int CRYPTO_atomic_add(int *val, int amount, int *ret, CRYPTO_RWLOCK *lock); 28 int CRYPTO_atomic_add64(uint64_t *val, uint64_t op, uint64_t *ret, 29 CRYPTO_RWLOCK *lock); 30 int CRYPTO_atomic_and(uint64_t *val, uint64_t op, uint64_t *ret, 31 CRYPTO_RWLOCK *lock); 32 int CRYPTO_atomic_or(uint64_t *val, uint64_t op, uint64_t *ret, 33 CRYPTO_RWLOCK *lock); 34 int CRYPTO_atomic_load(uint64_t *val, uint64_t *ret, CRYPTO_RWLOCK *lock); 35 int CRYPTO_atomic_store(uint64_t *dst, uint64_t val, CRYPTO_RWLOCK *lock); 36 int CRYPTO_atomic_load_int(int *val, int *ret, CRYPTO_RWLOCK *lock); 37 38 int OSSL_set_max_threads(OSSL_LIB_CTX *ctx, uint64_t max_threads); 39 uint64_t OSSL_get_max_threads(OSSL_LIB_CTX *ctx); 40 uint32_t OSSL_get_thread_support_flags(void); 41 42 #define OSSL_THREAD_SUPPORT_FLAG_THREAD_POOL 43 #define OSSL_THREAD_SUPPORT_FLAG_DEFAULT_SPAWN 44 45=head1 DESCRIPTION 46 47OpenSSL can be safely used in multi-threaded applications provided that 48support for the underlying OS threading API is built-in. Currently, OpenSSL 49supports the pthread and Windows APIs. OpenSSL can also be built without 50any multi-threading support, for example on platforms that don't provide 51any threading support or that provide a threading API that is not yet 52supported by OpenSSL. 53 54The following multi-threading function are provided: 55 56=over 2 57 58=item * 59 60CRYPTO_THREAD_run_once() can be used to perform one-time initialization. 61The I<once> argument must be a pointer to a static object of type 62B<CRYPTO_ONCE> that was statically initialized to the value 63B<CRYPTO_ONCE_STATIC_INIT>. 64The I<init> argument is a pointer to a function that performs the desired 65exactly once initialization. 66In particular, this can be used to allocate locks in a thread-safe manner, 67which can then be used with the locking functions below. 68 69=item * 70 71CRYPTO_THREAD_lock_new() allocates, initializes and returns a new read/write 72lock. 73 74=item * 75 76CRYPTO_THREAD_read_lock() locks the provided I<lock> for reading. 77 78=item * 79 80CRYPTO_THREAD_write_lock() locks the provided I<lock> for writing. 81 82=item * 83 84CRYPTO_THREAD_unlock() unlocks the previously locked I<lock>. 85 86=item * 87 88CRYPTO_THREAD_lock_free() frees the provided I<lock>. 89If the argument is NULL, nothing is done. 90 91=item * 92 93CRYPTO_atomic_add() atomically adds I<amount> to I<*val> and returns the 94result of the operation in I<*ret>. I<lock> will be locked, unless atomic 95operations are supported on the specific platform. Because of this, if a 96variable is modified by CRYPTO_atomic_add() then CRYPTO_atomic_add() must 97be the only way that the variable is modified. If atomic operations are not 98supported and I<lock> is NULL, then the function will fail. 99 100=item * 101 102CRYPTO_atomic_add64() atomically adds I<op> to I<*val> and returns the 103result of the operation in I<*ret>. I<lock> will be locked, unless atomic 104operations are supported on the specific platform. Because of this, if a 105variable is modified by CRYPTO_atomic_add64() then CRYPTO_atomic_add64() must 106be the only way that the variable is modified. If atomic operations are not 107supported and I<lock> is NULL, then the function will fail. 108 109=item * 110 111CRYPTO_atomic_and() performs an atomic bitwise and of I<op> and I<*val> and stores 112the result back in I<*val>. It also returns the result of the operation in 113I<*ret>. I<lock> will be locked, unless atomic operations are supported on the 114specific platform. Because of this, if a variable is modified by 115CRYPTO_atomic_and() or read by CRYPTO_atomic_load() then CRYPTO_atomic_and() must 116be the only way that the variable is modified. If atomic operations are not 117supported and I<lock> is NULL, then the function will fail. 118 119=item * 120 121CRYPTO_atomic_or() performs an atomic bitwise or of I<op> and I<*val> and stores 122the result back in I<*val>. It also returns the result of the operation in 123I<*ret>. I<lock> will be locked, unless atomic operations are supported on the 124specific platform. Because of this, if a variable is modified by 125CRYPTO_atomic_or() or read by CRYPTO_atomic_load() then CRYPTO_atomic_or() must 126be the only way that the variable is modified. If atomic operations are not 127supported and I<lock> is NULL, then the function will fail. 128 129=item * 130 131CRYPTO_atomic_load() atomically loads the contents of I<*val> into I<*ret>. 132I<lock> will be locked, unless atomic operations are supported on the specific 133platform. Because of this, if a variable is modified by CRYPTO_atomic_or() or 134read by CRYPTO_atomic_load() then CRYPTO_atomic_load() must be the only way that 135the variable is read. If atomic operations are not supported and I<lock> is 136NULL, then the function will fail. 137 138=item * 139 140CRYPTO_atomic_store() atomically stores the contents of I<val> into I<*dst>. 141I<lock> will be locked, unless atomic operations are supported on the specific 142platform. 143 144=item * 145 146CRYPTO_atomic_load_int() works identically to CRYPTO_atomic_load() but operates 147on an I<int> value instead of a I<uint64_t> value. 148 149=item * 150 151OSSL_set_max_threads() sets the maximum number of threads to be used by the 152thread pool. If the argument is 0, thread pooling is disabled. OpenSSL will 153not create any threads and existing threads in the thread pool will be torn 154down. The maximum thread count is a limit, not a target. Threads will not be 155spawned unless (and until) there is demand. Thread polling is disabled by 156default. To enable threading you must call OSSL_set_max_threads() explicitly. 157Under no circumstances is this done for you. 158 159=item * 160 161OSSL_get_thread_support_flags() determines what thread pool functionality 162OpenSSL is compiled with and is able to support in the current run time 163environment. B<OSSL_THREAD_SUPPORT_FLAG_THREAD_POOL> indicates that the base 164thread pool functionality is available, and 165B<OSSL_THREAD_SUPPORT_FLAG_DEFAULT_SPAWN> indicates that the default thread pool 166model is available. The default thread pool model is currently the only model 167available, therefore both of these flags must be set for thread pool 168functionality to be used. 169 170=back 171 172=head1 RETURN VALUES 173 174CRYPTO_THREAD_run_once() returns 1 on success, or 0 on error. 175 176CRYPTO_THREAD_lock_new() returns the allocated lock, or NULL on error. 177 178CRYPTO_THREAD_lock_free() returns no value. 179 180OSSL_set_max_threads() returns 1 on success and 0 on failure. Returns failure 181if OpenSSL-managed thread pooling is not supported (for example, if it is not 182supported on the current platform, or because OpenSSL is not built with the 183necessary support). 184 185OSSL_get_max_threads() returns the maximum number of threads currently allowed 186to be used by the thread pool. If thread pooling is disabled or not available, 187returns 0. 188 189OSSL_get_thread_support_flags() returns zero or more B<OSSL_THREAD_SUPPORT_FLAG> 190values. 191 192The other functions return 1 on success, or 0 on error. 193 194=head1 NOTES 195 196On Windows platforms the CRYPTO_THREAD_* types and functions in the 197F<< <openssl/crypto.h> >> header are dependent on some of the types 198customarily made available by including F<< <windows.h> >>. The application 199developer is likely to require control over when the latter is included, 200commonly as one of the first included headers. Therefore, it is defined as an 201application developer's responsibility to include F<< <windows.h> >> prior to 202F<< <openssl/crypto.h> >> where use of CRYPTO_THREAD_* types and functions is 203required. 204 205=head1 EXAMPLES 206 207You can find out if OpenSSL was configured with thread support: 208 209 #include <openssl/opensslconf.h> 210 #if defined(OPENSSL_THREADS) 211 /* thread support enabled */ 212 #else 213 /* no thread support */ 214 #endif 215 216This example safely initializes and uses a lock. 217 218 #ifdef _WIN32 219 # include <windows.h> 220 #endif 221 #include <openssl/crypto.h> 222 223 static CRYPTO_ONCE once = CRYPTO_ONCE_STATIC_INIT; 224 static CRYPTO_RWLOCK *lock; 225 226 static void myinit(void) 227 { 228 lock = CRYPTO_THREAD_lock_new(); 229 } 230 231 static int mylock(void) 232 { 233 if (!CRYPTO_THREAD_run_once(&once, void init) || lock == NULL) 234 return 0; 235 return CRYPTO_THREAD_write_lock(lock); 236 } 237 238 static int myunlock(void) 239 { 240 return CRYPTO_THREAD_unlock(lock); 241 } 242 243 int serialized(void) 244 { 245 int ret = 0; 246 247 if (!mylock()) { 248 /* Do not unlock unless the lock was successfully acquired. */ 249 return 0; 250 } 251 252 /* Your code here, do not return without releasing the lock! */ 253 ret = ... ; 254 myunlock(); 255 return ret; 256 } 257 258Finalization of locks is an advanced topic, not covered in this example. 259This can only be done at process exit or when a dynamically loaded library is 260no longer in use and is unloaded. 261The simplest solution is to just "leak" the lock in applications and not 262repeatedly load/unload shared libraries that allocate locks. 263 264=head1 SEE ALSO 265 266L<crypto(7)>, L<openssl-threads(7)>. 267 268=head1 HISTORY 269 270CRYPTO_atomic_store() was added in OpenSSL 3.4.0 271 272=head1 COPYRIGHT 273 274Copyright 2000-2024 The OpenSSL Project Authors. All Rights Reserved. 275 276Licensed under the Apache License 2.0 (the "License"). You may not use 277this file except in compliance with the License. You can obtain a copy 278in the file LICENSE in the source distribution or at 279L<https://www.openssl.org/source/license.html>. 280 281=cut 282