X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=doc%2Fcrypto%2Fthreads.pod;h=bb21462f3e08ac8e3133242a869b755d8576087d;hp=90c57098a46957da0a43b10862acb1cadb1ef6c6;hb=5c4328f04f63bc288d4e069e1453ab18b0309f16;hpb=b160f2823fb3bafdf8728ea251aab0d07888b934 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