=pod =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 =head1 SYNOPSIS #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); 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); =head1 DESCRIPTION OpenSSL can be safely used in multi-threaded applications provided that support for the underlying OS threading API is built-in. Currently, OpenSSL supports the pthread and Windows APIs. OpenSSL can also be built without any multi-threading support, for example on platforms that don't provide any threading support or that provide a threading API that is not yet supported by OpenSSL. 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. =item * CRYPTO_THREAD_read_lock() locks the provided B for reading. =item * CRYPTO_THREAD_write_lock() locks the provided B for writing. =item * CRYPTO_THREAD_unlock() unlocks the previously locked B. =item * CRYPTO_THREAD_lock_frees() frees the provided B. =item * CRYPTO_atomic_add() atomically adds B to B and returns the result of the operation in B. B will be locked, unless atomic 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. =back =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: #include #if defined(OPENSSL_THREADS) // thread support enabled #else // no thread support #endif =head1 SEE ALSO L =head1 COPYRIGHT Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved. Licensed under the OpenSSL license (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 L. =cut