5 CRYPTO_THREAD_run_once,
6 CRYPTO_THREAD_lock_new, CRYPTO_THREAD_read_lock, CRYPTO_THREAD_write_lock,
7 CRYPTO_THREAD_unlock, CRYPTO_THREAD_lock_free, CRYPTO_atomic_add - OpenSSL thread support
11 #include <openssl/crypto.h>
13 CRYPTO_ONCE CRYPTO_ONCE_STATIC_INIT;
14 int CRYPTO_THREAD_run_once(CRYPTO_ONCE *once, void (*init)(void));
16 CRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void);
17 int CRYPTO_THREAD_read_lock(CRYPTO_RWLOCK *lock);
18 int CRYPTO_THREAD_write_lock(CRYPTO_RWLOCK *lock);
19 int CRYPTO_THREAD_unlock(CRYPTO_RWLOCK *lock);
20 void CRYPTO_THREAD_lock_free(CRYPTO_RWLOCK *lock);
22 int CRYPTO_atomic_add(int *val, int amount, int *ret, CRYPTO_RWLOCK *lock);
26 OpenSSL can be safely used in multi-threaded applications provided that
27 support for the underlying OS threading API is built-in. Currently, OpenSSL
28 supports the pthread and Windows APIs. OpenSSL can also be built without
29 any multi-threading support, for example on platforms that don't provide
30 any threading support or that provide a threading API that is not yet
33 The following multi-threading function are provided:
38 CRYPTO_THREAD_run_once() can be used to perform one-time initialization.
39 The B<once> argument must be a pointer to a static object of type
40 B<CRYPTO_ONCE> that was statically initialized to the value
41 B<CRYPTO_ONCE_STATIC_INIT>.
42 The B<init> argument is a pointer to a function that performs the desired
43 exactly once initialization.
44 In particular, this can be used to allocate locks in a thread-safe manner,
45 which can then be used with the locking functions below.
48 CRYPTO_THREAD_lock_new() allocates, initializes and returns a new read/write
52 CRYPTO_THREAD_read_lock() locks the provided B<lock> for reading.
55 CRYPTO_THREAD_write_lock() locks the provided B<lock> for writing.
58 CRYPTO_THREAD_unlock() unlocks the previously locked B<lock>.
61 CRYPTO_THREAD_lock_frees() frees the provided B<lock>.
64 CRYPTO_atomic_add() atomically adds B<amount> to B<val> and returns the
65 result of the operation in B<ret>. B<lock> will be locked, unless atomic
66 operations are supported on the specific platform. Because of this, if a
67 variable is modified by CRYPTO_atomic_add() then CRYPTO_atomic_add() must
68 be the only way that the variable is modified.
74 CRYPTO_THREAD_run_once() returns 1 on success, or 0 on error.
76 CRYPTO_THREAD_lock_new() returns the allocated lock, or NULL on error.
78 CRYPTO_THREAD_lock_frees() returns no value.
80 The other functions return 1 on success or 0 on error.
84 This example safely initializes and uses a lock.
86 #include <openssl/crypto.h>
88 static CRYPTO_ONCE once = CRYPTO_ONCE_STATIC_INIT;
89 static CRYPTO_RWLOCK *lock;
91 static void myinit(void)
93 lock = CRYPTO_THREAD_lock_new();
96 static int mylock(void)
98 if (!CRYPTO_THREAD_run_once(&once, void init) || lock == NULL)
100 return CRYPTO_THREAD_write_lock(lock);
103 static int myunlock(void)
105 return CRYPTO_THREAD_unlock(lock);
113 /* Your code here, do not return without releasing the lock! */
120 Finalization of locks is an advanced topic, not covered in this example.
121 This can only be done at process exit or when a dynamically loaded library is
122 no longer in use and is unloaded.
123 The simplest solution is to just "leak" the lock in applications and not
124 repeatedly load/unload shared libraries that allocate locks.
128 You can find out if OpenSSL was configured with thread support:
130 #include <openssl/opensslconf.h>
131 #if defined(OPENSSL_THREADS)
132 // thread support enabled