| 
									
										
										
										
											2000-02-24 02:10:42 +08:00
										 |  |  | =pod | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | =head1 NAME | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-16 01:02:17 +08:00
										 |  |  | CRYPTO_THREAD_run_once, | 
					
						
							| 
									
										
										
										
											2015-10-26 00:43:55 +08:00
										 |  |  | CRYPTO_THREAD_lock_new, CRYPTO_THREAD_read_lock, CRYPTO_THREAD_write_lock, | 
					
						
							| 
									
										
										
										
											2017-09-25 10:04:42 +08:00
										 |  |  | CRYPTO_THREAD_unlock, CRYPTO_THREAD_lock_free, CRYPTO_atomic_add, | 
					
						
							| 
									
										
										
										
											2017-10-09 12:39:43 +08:00
										 |  |  | CRYPTO_atomic_read, CRYPTO_atomic_write - OpenSSL thread support | 
					
						
							| 
									
										
										
										
											2000-02-24 02:10:42 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | =head1 SYNOPSIS | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  #include <openssl/crypto.h> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-16 01:02:17 +08:00
										 |  |  |  CRYPTO_ONCE CRYPTO_ONCE_STATIC_INIT; | 
					
						
							|  |  |  |  int CRYPTO_THREAD_run_once(CRYPTO_ONCE *once, void (*init)(void)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-26 00:43:55 +08:00
										 |  |  |  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); | 
					
						
							| 
									
										
										
										
											2017-09-25 10:04:42 +08:00
										 |  |  |  int CRYPTO_atomic_read(int *val, int *ret, CRYPTO_RWLOCK *lock); | 
					
						
							| 
									
										
										
										
											2017-10-09 12:39:43 +08:00
										 |  |  |  int CRYPTO_atomic_write(int *val, int n, CRYPTO_RWLOCK *lock); | 
					
						
							| 
									
										
										
										
											2000-09-15 05:23:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-24 02:10:42 +08:00
										 |  |  | =head1 DESCRIPTION | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-26 00:43:55 +08:00
										 |  |  | 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: | 
					
						
							| 
									
										
										
										
											2008-08-06 23:54:15 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-08 01:37:47 +08:00
										 |  |  | =over 2 | 
					
						
							| 
									
										
										
										
											2008-08-06 23:54:15 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-16 01:02:17 +08:00
										 |  |  | =item * | 
					
						
							| 
									
										
										
										
											2017-04-08 01:37:47 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-16 01:02:17 +08:00
										 |  |  | CRYPTO_THREAD_run_once() can be used to perform one-time initialization. | 
					
						
							|  |  |  | The B<once> argument must be a pointer to a static object of type | 
					
						
							|  |  |  | B<CRYPTO_ONCE> that was statically initialized to the value | 
					
						
							|  |  |  | B<CRYPTO_ONCE_STATIC_INIT>. | 
					
						
							|  |  |  | The B<init> 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. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-06 23:54:15 +08:00
										 |  |  | =item * | 
					
						
							| 
									
										
										
										
											2017-04-08 01:37:47 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-26 00:43:55 +08:00
										 |  |  | CRYPTO_THREAD_lock_new() allocates, initializes and returns a new read/write | 
					
						
							|  |  |  | lock. | 
					
						
							| 
									
										
										
										
											2008-08-06 23:54:15 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | =item * | 
					
						
							| 
									
										
										
										
											2017-04-08 01:37:47 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-26 00:43:55 +08:00
										 |  |  | CRYPTO_THREAD_read_lock() locks the provided B<lock> for reading. | 
					
						
							| 
									
										
										
										
											2008-08-06 23:54:15 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | =item * | 
					
						
							| 
									
										
										
										
											2017-04-08 01:37:47 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-26 00:43:55 +08:00
										 |  |  | CRYPTO_THREAD_write_lock() locks the provided B<lock> for writing. | 
					
						
							| 
									
										
										
										
											2008-08-06 23:54:15 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | =item * | 
					
						
							| 
									
										
										
										
											2017-04-08 01:37:47 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-26 00:43:55 +08:00
										 |  |  | CRYPTO_THREAD_unlock() unlocks the previously locked B<lock>. | 
					
						
							| 
									
										
										
										
											2000-09-15 04:22:14 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-06-18 23:59:04 +08:00
										 |  |  | =item * | 
					
						
							| 
									
										
										
										
											2017-04-08 01:37:47 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-09 15:52:56 +08:00
										 |  |  | CRYPTO_THREAD_lock_free() frees the provided B<lock>. | 
					
						
							| 
									
										
										
										
											2000-06-18 23:59:04 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | =item * | 
					
						
							| 
									
										
										
										
											2017-04-08 01:37:47 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-26 00:43:55 +08:00
										 |  |  | CRYPTO_atomic_add() atomically adds B<amount> to B<val> and returns the | 
					
						
							|  |  |  | result of the operation in B<ret>. B<lock> 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. | 
					
						
							| 
									
										
										
										
											2000-06-18 23:59:04 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-25 10:04:42 +08:00
										 |  |  | =item * | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | CRYPTO_atomic_read() atomically reads B<val> and returns the result of | 
					
						
							|  |  |  | the operation in B<ret>. B<lock> will be locked, unless atomic operations | 
					
						
							|  |  |  | are supported on the specific platform. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-09 12:39:43 +08:00
										 |  |  | =item * | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | CRYPTO_atomic_write() atomically writes B<n> to B<val>. B<lock> will be | 
					
						
							|  |  |  | locked, unless atomic operations are supported on the specific platform. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-09-15 04:22:14 +08:00
										 |  |  | =back | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-24 09:20:31 +08:00
										 |  |  | =head1 RETURN VALUES | 
					
						
							| 
									
										
										
										
											2000-02-24 08:22:17 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-16 01:02:17 +08:00
										 |  |  | CRYPTO_THREAD_run_once() returns 1 on success, or 0 on error. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-26 00:43:55 +08:00
										 |  |  | CRYPTO_THREAD_lock_new() returns the allocated lock, or NULL on error. | 
					
						
							| 
									
										
										
										
											2000-06-18 23:59:04 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-09 15:52:56 +08:00
										 |  |  | CRYPTO_THREAD_lock_free() returns no value. | 
					
						
							| 
									
										
										
										
											2000-06-18 23:59:04 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-09 15:52:56 +08:00
										 |  |  | The other functions return 1 on success, or 0 on error. | 
					
						
							| 
									
										
										
										
											2000-02-24 08:22:17 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-26 19:40:15 +08:00
										 |  |  | =head1 NOTES | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | On Windows platforms the CRYPTO_THREAD_* types and functions in the | 
					
						
							|  |  |  | openssl/crypto.h header are dependent on some of the types customarily | 
					
						
							|  |  |  | made available by including windows.h. The application developer is | 
					
						
							|  |  |  | likely to require control over when the latter is included, commonly as | 
					
						
							|  |  |  | one of the first included headers. Therefore it is defined as an | 
					
						
							|  |  |  | application developer's responsibility to include windows.h prior to | 
					
						
							|  |  |  | crypto.h where use of CRYPTO_THREAD_* types and functions is required. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-16 01:02:17 +08:00
										 |  |  | =head1 EXAMPLE | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This example safely initializes and uses a lock. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-19 07:10:05 +08:00
										 |  |  |  #ifdef _WIN32 | 
					
						
							|  |  |  |  # include <windows.h> | 
					
						
							|  |  |  |  #endif | 
					
						
							|  |  |  |  #include <openssl/crypto.h> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  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; | 
					
						
							|  |  |  |  } | 
					
						
							| 
									
										
										
										
											2016-05-16 01:02:17 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-06-18 13:52:16 +08:00
										 |  |  | =head1 NOTES | 
					
						
							| 
									
										
										
										
											2000-02-24 02:10:42 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | You can find out if OpenSSL was configured with thread support: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  #include <openssl/opensslconf.h> | 
					
						
							| 
									
										
										
										
											2005-06-04 16:44:02 +08:00
										 |  |  |  #if defined(OPENSSL_THREADS) | 
					
						
							| 
									
										
										
										
											2017-04-04 01:52:33 +08:00
										 |  |  |      /* thread support enabled */ | 
					
						
							| 
									
										
										
										
											2000-02-24 02:10:42 +08:00
										 |  |  |  #else | 
					
						
							| 
									
										
										
										
											2017-04-04 01:52:33 +08:00
										 |  |  |      /* no thread support */ | 
					
						
							| 
									
										
										
										
											2000-02-24 02:10:42 +08:00
										 |  |  |  #endif | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | =head1 SEE ALSO | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-11 16:33:09 +08:00
										 |  |  | L<crypto(7)> | 
					
						
							| 
									
										
										
										
											2000-02-24 02:10:42 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-18 23:44:05 +08:00
										 |  |  | =head1 COPYRIGHT | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-13 20:51:29 +08:00
										 |  |  | Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved. | 
					
						
							| 
									
										
										
										
											2016-05-18 23:44:05 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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<https://www.openssl.org/source/license.html>. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | =cut |