a290278b70d57e0b544184edd53460d5c100b5fb
[openssl.git] / doc / man3 / CRYPTO_THREAD_run_once.pod
1 =pod
2
3 =head1 NAME
4
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,
8 CRYPTO_atomic_read, CRYPTO_atomic_write - OpenSSL thread support
9
10 =head1 SYNOPSIS
11
12  #include <openssl/crypto.h>
13
14  CRYPTO_ONCE CRYPTO_ONCE_STATIC_INIT;
15  int CRYPTO_THREAD_run_once(CRYPTO_ONCE *once, void (*init)(void));
16
17  CRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void);
18  int CRYPTO_THREAD_read_lock(CRYPTO_RWLOCK *lock);
19  int CRYPTO_THREAD_write_lock(CRYPTO_RWLOCK *lock);
20  int CRYPTO_THREAD_unlock(CRYPTO_RWLOCK *lock);
21  void CRYPTO_THREAD_lock_free(CRYPTO_RWLOCK *lock);
22
23  int CRYPTO_atomic_add(int *val, int amount, int *ret, CRYPTO_RWLOCK *lock);
24  int CRYPTO_atomic_read(int *val, int *ret, CRYPTO_RWLOCK *lock);
25  int CRYPTO_atomic_write(int *val, int n, CRYPTO_RWLOCK *lock);
26
27 =head1 DESCRIPTION
28
29 OpenSSL can be safely used in multi-threaded applications provided that
30 support for the underlying OS threading API is built-in. Currently, OpenSSL
31 supports the pthread and Windows APIs. OpenSSL can also be built without
32 any multi-threading support, for example on platforms that don't provide
33 any threading support or that provide a threading API that is not yet
34 supported by OpenSSL.
35
36 The following multi-threading function are provided:
37
38 =over 2
39
40 =item *
41
42 CRYPTO_THREAD_run_once() can be used to perform one-time initialization.
43 The B<once> argument must be a pointer to a static object of type
44 B<CRYPTO_ONCE> that was statically initialized to the value
45 B<CRYPTO_ONCE_STATIC_INIT>.
46 The B<init> argument is a pointer to a function that performs the desired
47 exactly once initialization.
48 In particular, this can be used to allocate locks in a thread-safe manner,
49 which can then be used with the locking functions below.
50
51 =item *
52
53 CRYPTO_THREAD_lock_new() allocates, initializes and returns a new read/write
54 lock.
55
56 =item *
57
58 CRYPTO_THREAD_read_lock() locks the provided B<lock> for reading.
59
60 =item *
61
62 CRYPTO_THREAD_write_lock() locks the provided B<lock> for writing.
63
64 =item *
65
66 CRYPTO_THREAD_unlock() unlocks the previously locked B<lock>.
67
68 =item *
69
70 CRYPTO_THREAD_lock_free() frees the provided B<lock>.
71
72 =item *
73
74 CRYPTO_atomic_add() atomically adds B<amount> to B<val> and returns the
75 result of the operation in B<ret>. B<lock> will be locked, unless atomic
76 operations are supported on the specific platform. Because of this, if a
77 variable is modified by CRYPTO_atomic_add() then CRYPTO_atomic_add() must
78 be the only way that the variable is modified.
79
80 =item *
81
82 CRYPTO_atomic_read() atomically reads B<val> and returns the result of
83 the operation in B<ret>. B<lock> will be locked, unless atomic operations
84 are supported on the specific platform.
85
86 =item *
87
88 CRYPTO_atomic_write() atomically writes B<n> to B<val>. B<lock> will be
89 locked, unless atomic operations are supported on the specific platform.
90
91 =back
92
93 =head1 RETURN VALUES
94
95 CRYPTO_THREAD_run_once() returns 1 on success, or 0 on error.
96
97 CRYPTO_THREAD_lock_new() returns the allocated lock, or NULL on error.
98
99 CRYPTO_THREAD_lock_free() returns no value.
100
101 The other functions return 1 on success, or 0 on error.
102
103 =head1 NOTES
104
105 On Windows platforms the CRYPTO_THREAD_* types and functions in the
106 openssl/crypto.h header are dependent on some of the types customarily
107 made available by including windows.h. The application developer is
108 likely to require control over when the latter is included, commonly as
109 one of the first included headers. Therefore it is defined as an
110 application developer's responsibility to include windows.h prior to
111 crypto.h where use of CRYPTO_THREAD_* types and functions is required.
112
113 =head1 EXAMPLE
114
115 This example safely initializes and uses a lock.
116
117  #ifdef _WIN32
118  # include <windows.h>
119  #endif
120  #include <openssl/crypto.h>
121
122  static CRYPTO_ONCE once = CRYPTO_ONCE_STATIC_INIT;
123  static CRYPTO_RWLOCK *lock;
124
125  static void myinit(void)
126  {
127      lock = CRYPTO_THREAD_lock_new();
128  }
129
130  static int mylock(void)
131  {
132      if (!CRYPTO_THREAD_run_once(&once, void init) || lock == NULL)
133          return 0;
134      return CRYPTO_THREAD_write_lock(lock);
135  }
136
137  static int myunlock(void)
138  {
139      return CRYPTO_THREAD_unlock(lock);
140  }
141
142  int serialized(void)
143  {
144      int ret = 0;
145
146      if (mylock()) {
147          /* Your code here, do not return without releasing the lock! */
148          ret = ... ;
149      }
150      myunlock();
151      return ret;
152  }
153
154 Finalization of locks is an advanced topic, not covered in this example.
155 This can only be done at process exit or when a dynamically loaded library is
156 no longer in use and is unloaded.
157 The simplest solution is to just "leak" the lock in applications and not
158 repeatedly load/unload shared libraries that allocate locks.
159
160 =head1 NOTES
161
162 You can find out if OpenSSL was configured with thread support:
163
164  #include <openssl/opensslconf.h>
165  #if defined(OPENSSL_THREADS)
166      /* thread support enabled */
167  #else
168      /* no thread support */
169  #endif
170
171 =head1 SEE ALSO
172
173 L<crypto(7)>
174
175 =head1 COPYRIGHT
176
177 Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved.
178
179 Licensed under the OpenSSL license (the "License").  You may not use
180 this file except in compliance with the License.  You can obtain a copy
181 in the file LICENSE in the source distribution or at
182 L<https://www.openssl.org/source/license.html>.
183
184 =cut