bb21462f3e08ac8e3133242a869b755d8576087d
[openssl.git] / doc / crypto / threads.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 - OpenSSL thread support
8
9 =head1 SYNOPSIS
10
11  #include <openssl/crypto.h>
12
13  CRYPTO_ONCE CRYPTO_ONCE_STATIC_INIT;
14  int CRYPTO_THREAD_run_once(CRYPTO_ONCE *once, void (*init)(void));
15
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);
21
22  int CRYPTO_atomic_add(int *val, int amount, int *ret, CRYPTO_RWLOCK *lock);
23
24 =head1 DESCRIPTION
25
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
31 supported by OpenSSL.
32
33 The following multi-threading function are provided:
34
35 =over 4
36
37 =item *
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.
46
47 =item *
48 CRYPTO_THREAD_lock_new() allocates, initializes and returns a new read/write
49 lock.
50
51 =item *
52 CRYPTO_THREAD_read_lock() locks the provided B<lock> for reading.
53
54 =item *
55 CRYPTO_THREAD_write_lock() locks the provided B<lock> for writing.
56
57 =item *
58 CRYPTO_THREAD_unlock() unlocks the previously locked B<lock>.
59
60 =item *
61 CRYPTO_THREAD_lock_frees() frees the provided B<lock>.
62
63 =item *
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.
69
70 =back
71
72 =head1 RETURN VALUES
73
74 CRYPTO_THREAD_run_once() returns 1 on success, or 0 on error.
75
76 CRYPTO_THREAD_lock_new() returns the allocated lock, or NULL on error.
77
78 CRYPTO_THREAD_lock_frees() returns no value.
79
80 The other functions return 1 on success or 0 on error.
81
82 =head1 EXAMPLE
83
84 This example safely initializes and uses a lock.
85
86   #include <openssl/crypto.h>
87   
88   static CRYPTO_ONCE once = CRYPTO_ONCE_STATIC_INIT;
89   static CRYPTO_RWLOCK *lock;
90   
91   static void myinit(void)
92   {
93       lock = CRYPTO_THREAD_lock_new();
94   }
95   
96   static int mylock(void)
97   {
98       if (!CRYPTO_THREAD_run_once(&once, void init) || lock == NULL)
99           return 0;
100       return CRYPTO_THREAD_write_lock(lock);
101   }
102   
103   static int myunlock(void)
104   {
105       return CRYPTO_THREAD_unlock(lock);
106   }
107   
108   int serialized(void)
109   {
110       int ret = 0;
111   
112       if (mylock()) {
113           /* Your code here, do not return without releasing the lock! */
114           ret = ... ;
115       }
116       myunlock();
117       return ret;
118   }
119
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.
125
126 =head1 NOTES
127
128 You can find out if OpenSSL was configured with thread support:
129
130  #include <openssl/opensslconf.h>
131  #if defined(OPENSSL_THREADS)
132    // thread support enabled
133  #else
134    // no thread support
135  #endif
136
137 =head1 SEE ALSO
138
139 L<crypto(3)>
140
141 =cut