]>
Commit | Line | Data |
---|---|---|
5705e050 | 1 | /* |
83cf7abf | 2 | * Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved. |
5705e050 | 3 | * |
440e5d80 RS |
4 | * Licensed under the OpenSSL license (the "License"). You may not use |
5 | * this file except in compliance with the License. You can obtain a copy | |
6 | * in the file LICENSE in the source distribution or at | |
7 | * https://www.openssl.org/source/license.html | |
5705e050 MC |
8 | */ |
9 | ||
f1f5ee17 AP |
10 | #ifdef _WIN32 |
11 | # include <windows.h> | |
12 | #endif | |
13 | ||
5705e050 MC |
14 | #include <stdio.h> |
15 | #include <string.h> | |
16 | #include <openssl/async.h> | |
17 | #include <openssl/crypto.h> | |
5705e050 | 18 | |
5705e050 MC |
19 | static int ctr = 0; |
20 | static ASYNC_JOB *currjob = NULL; | |
21 | ||
22 | static int only_pause(void *args) | |
23 | { | |
24 | ASYNC_pause_job(); | |
25 | ||
26 | return 1; | |
27 | } | |
28 | ||
29 | static int add_two(void *args) | |
30 | { | |
31 | ctr++; | |
32 | ASYNC_pause_job(); | |
33 | ctr++; | |
34 | ||
35 | return 2; | |
36 | } | |
37 | ||
38 | static int save_current(void *args) | |
39 | { | |
40 | currjob = ASYNC_get_current_job(); | |
41 | ASYNC_pause_job(); | |
42 | ||
43 | return 1; | |
44 | } | |
45 | ||
ff75a257 MC |
46 | #define MAGIC_WAIT_FD ((OSSL_ASYNC_FD)99) |
47 | static int waitfd(void *args) | |
5705e050 | 48 | { |
ff75a257 MC |
49 | ASYNC_JOB *job; |
50 | ASYNC_WAIT_CTX *waitctx; | |
ff75a257 MC |
51 | job = ASYNC_get_current_job(); |
52 | if (job == NULL) | |
53 | return 0; | |
54 | waitctx = ASYNC_get_wait_ctx(job); | |
55 | if (waitctx == NULL) | |
56 | return 0; | |
f44e6364 AG |
57 | |
58 | /* First case: no fd added or removed */ | |
59 | ASYNC_pause_job(); | |
60 | ||
61 | /* Second case: one fd added */ | |
e8aa8b6c | 62 | if (!ASYNC_WAIT_CTX_set_wait_fd(waitctx, waitctx, MAGIC_WAIT_FD, NULL, NULL)) |
ff75a257 | 63 | return 0; |
5705e050 | 64 | ASYNC_pause_job(); |
ff75a257 | 65 | |
f44e6364 AG |
66 | /* Third case: all fd removed */ |
67 | if (!ASYNC_WAIT_CTX_clear_fd(waitctx, waitctx)) | |
68 | return 0; | |
69 | ASYNC_pause_job(); | |
70 | ||
71 | /* Last case: fd added and immediately removed */ | |
72 | if (!ASYNC_WAIT_CTX_set_wait_fd(waitctx, waitctx, MAGIC_WAIT_FD, NULL, NULL)) | |
73 | return 0; | |
ff75a257 MC |
74 | if (!ASYNC_WAIT_CTX_clear_fd(waitctx, waitctx)) |
75 | return 0; | |
5705e050 MC |
76 | |
77 | return 1; | |
78 | } | |
79 | ||
e8dfb5bf MC |
80 | static int blockpause(void *args) |
81 | { | |
82 | ASYNC_block_pause(); | |
83 | ASYNC_pause_job(); | |
84 | ASYNC_unblock_pause(); | |
85 | ASYNC_pause_job(); | |
86 | ||
87 | return 1; | |
88 | } | |
89 | ||
3cb7c5cf | 90 | static int test_ASYNC_init_thread(void) |
5705e050 MC |
91 | { |
92 | ASYNC_JOB *job1 = NULL, *job2 = NULL, *job3 = NULL; | |
93 | int funcret1, funcret2, funcret3; | |
174a74ef | 94 | ASYNC_WAIT_CTX *waitctx = NULL; |
5705e050 | 95 | |
7b9f8f7f | 96 | if ( !ASYNC_init_thread(2, 0) |
ff75a257 MC |
97 | || (waitctx = ASYNC_WAIT_CTX_new()) == NULL |
98 | || ASYNC_start_job(&job1, waitctx, &funcret1, only_pause, NULL, 0) | |
5705e050 | 99 | != ASYNC_PAUSE |
ff75a257 | 100 | || ASYNC_start_job(&job2, waitctx, &funcret2, only_pause, NULL, 0) |
5705e050 | 101 | != ASYNC_PAUSE |
ff75a257 | 102 | || ASYNC_start_job(&job3, waitctx, &funcret3, only_pause, NULL, 0) |
5705e050 | 103 | != ASYNC_NO_JOBS |
ff75a257 | 104 | || ASYNC_start_job(&job1, waitctx, &funcret1, only_pause, NULL, 0) |
5705e050 | 105 | != ASYNC_FINISH |
ff75a257 | 106 | || ASYNC_start_job(&job3, waitctx, &funcret3, only_pause, NULL, 0) |
5705e050 | 107 | != ASYNC_PAUSE |
ff75a257 | 108 | || ASYNC_start_job(&job2, waitctx, &funcret2, only_pause, NULL, 0) |
5705e050 | 109 | != ASYNC_FINISH |
ff75a257 | 110 | || ASYNC_start_job(&job3, waitctx, &funcret3, only_pause, NULL, 0) |
5705e050 MC |
111 | != ASYNC_FINISH |
112 | || funcret1 != 1 | |
113 | || funcret2 != 1 | |
114 | || funcret3 != 1) { | |
7b9f8f7f | 115 | fprintf(stderr, "test_ASYNC_init_thread() failed\n"); |
ff75a257 | 116 | ASYNC_WAIT_CTX_free(waitctx); |
7b9f8f7f | 117 | ASYNC_cleanup_thread(); |
5705e050 MC |
118 | return 0; |
119 | } | |
120 | ||
ff75a257 | 121 | ASYNC_WAIT_CTX_free(waitctx); |
7b9f8f7f | 122 | ASYNC_cleanup_thread(); |
5705e050 MC |
123 | return 1; |
124 | } | |
125 | ||
3cb7c5cf | 126 | static int test_ASYNC_start_job(void) |
5705e050 MC |
127 | { |
128 | ASYNC_JOB *job = NULL; | |
129 | int funcret; | |
174a74ef | 130 | ASYNC_WAIT_CTX *waitctx = NULL; |
5705e050 MC |
131 | |
132 | ctr = 0; | |
133 | ||
7b9f8f7f | 134 | if ( !ASYNC_init_thread(1, 0) |
ff75a257 MC |
135 | || (waitctx = ASYNC_WAIT_CTX_new()) == NULL |
136 | || ASYNC_start_job(&job, waitctx, &funcret, add_two, NULL, 0) | |
137 | != ASYNC_PAUSE | |
5705e050 | 138 | || ctr != 1 |
ff75a257 MC |
139 | || ASYNC_start_job(&job, waitctx, &funcret, add_two, NULL, 0) |
140 | != ASYNC_FINISH | |
5705e050 MC |
141 | || ctr != 2 |
142 | || funcret != 2) { | |
143 | fprintf(stderr, "test_ASYNC_start_job() failed\n"); | |
ff75a257 | 144 | ASYNC_WAIT_CTX_free(waitctx); |
7b9f8f7f | 145 | ASYNC_cleanup_thread(); |
5705e050 MC |
146 | return 0; |
147 | } | |
148 | ||
ff75a257 | 149 | ASYNC_WAIT_CTX_free(waitctx); |
7b9f8f7f | 150 | ASYNC_cleanup_thread(); |
5705e050 MC |
151 | return 1; |
152 | } | |
153 | ||
3cb7c5cf | 154 | static int test_ASYNC_get_current_job(void) |
5705e050 MC |
155 | { |
156 | ASYNC_JOB *job = NULL; | |
157 | int funcret; | |
174a74ef | 158 | ASYNC_WAIT_CTX *waitctx = NULL; |
5705e050 MC |
159 | |
160 | currjob = NULL; | |
161 | ||
7b9f8f7f | 162 | if ( !ASYNC_init_thread(1, 0) |
ff75a257 MC |
163 | || (waitctx = ASYNC_WAIT_CTX_new()) == NULL |
164 | || ASYNC_start_job(&job, waitctx, &funcret, save_current, NULL, 0) | |
5705e050 MC |
165 | != ASYNC_PAUSE |
166 | || currjob != job | |
ff75a257 | 167 | || ASYNC_start_job(&job, waitctx, &funcret, save_current, NULL, 0) |
5705e050 MC |
168 | != ASYNC_FINISH |
169 | || funcret != 1) { | |
170 | fprintf(stderr, "test_ASYNC_get_current_job() failed\n"); | |
ff75a257 | 171 | ASYNC_WAIT_CTX_free(waitctx); |
7b9f8f7f | 172 | ASYNC_cleanup_thread(); |
5705e050 MC |
173 | return 0; |
174 | } | |
175 | ||
ff75a257 | 176 | ASYNC_WAIT_CTX_free(waitctx); |
7b9f8f7f | 177 | ASYNC_cleanup_thread(); |
5705e050 MC |
178 | return 1; |
179 | } | |
180 | ||
3cb7c5cf | 181 | static int test_ASYNC_WAIT_CTX_get_all_fds(void) |
5705e050 MC |
182 | { |
183 | ASYNC_JOB *job = NULL; | |
2b2c78d4 | 184 | int funcret; |
174a74ef | 185 | ASYNC_WAIT_CTX *waitctx = NULL; |
ff75a257 MC |
186 | OSSL_ASYNC_FD fd = OSSL_BAD_ASYNC_FD, delfd = OSSL_BAD_ASYNC_FD; |
187 | size_t numfds, numdelfds; | |
5705e050 | 188 | |
7b9f8f7f | 189 | if ( !ASYNC_init_thread(1, 0) |
ff75a257 MC |
190 | || (waitctx = ASYNC_WAIT_CTX_new()) == NULL |
191 | /* On first run we're not expecting any wait fds */ | |
192 | || ASYNC_start_job(&job, waitctx, &funcret, waitfd, NULL, 0) | |
5705e050 | 193 | != ASYNC_PAUSE |
ff75a257 MC |
194 | || !ASYNC_WAIT_CTX_get_all_fds(waitctx, NULL, &numfds) |
195 | || numfds != 0 | |
196 | || !ASYNC_WAIT_CTX_get_changed_fds(waitctx, NULL, &numfds, NULL, | |
197 | &numdelfds) | |
198 | || numfds != 0 | |
199 | || numdelfds != 0 | |
200 | /* On second run we're expecting one added fd */ | |
201 | || ASYNC_start_job(&job, waitctx, &funcret, waitfd, NULL, 0) | |
5705e050 | 202 | != ASYNC_PAUSE |
ff75a257 MC |
203 | || !ASYNC_WAIT_CTX_get_all_fds(waitctx, NULL, &numfds) |
204 | || numfds != 1 | |
205 | || !ASYNC_WAIT_CTX_get_all_fds(waitctx, &fd, &numfds) | |
206 | || fd != MAGIC_WAIT_FD | |
207 | || (fd = OSSL_BAD_ASYNC_FD, 0) /* Assign to something else */ | |
208 | || !ASYNC_WAIT_CTX_get_changed_fds(waitctx, NULL, &numfds, NULL, | |
f44e6364 | 209 | &numdelfds) |
ff75a257 MC |
210 | || numfds != 1 |
211 | || numdelfds != 0 | |
212 | || !ASYNC_WAIT_CTX_get_changed_fds(waitctx, &fd, &numfds, NULL, | |
213 | &numdelfds) | |
214 | || fd != MAGIC_WAIT_FD | |
f44e6364 | 215 | /* On third run we expect one deleted fd */ |
ff75a257 | 216 | || ASYNC_start_job(&job, waitctx, &funcret, waitfd, NULL, 0) |
f44e6364 | 217 | != ASYNC_PAUSE |
ff75a257 MC |
218 | || !ASYNC_WAIT_CTX_get_all_fds(waitctx, NULL, &numfds) |
219 | || numfds != 0 | |
220 | || !ASYNC_WAIT_CTX_get_changed_fds(waitctx, NULL, &numfds, NULL, | |
221 | &numdelfds) | |
222 | || numfds != 0 | |
223 | || numdelfds != 1 | |
224 | || !ASYNC_WAIT_CTX_get_changed_fds(waitctx, NULL, &numfds, &delfd, | |
225 | &numdelfds) | |
226 | || delfd != MAGIC_WAIT_FD | |
f44e6364 AG |
227 | /* On last run we are not expecting any wait fd */ |
228 | || ASYNC_start_job(&job, waitctx, &funcret, waitfd, NULL, 0) | |
229 | != ASYNC_FINISH | |
230 | || !ASYNC_WAIT_CTX_get_all_fds(waitctx, NULL, &numfds) | |
231 | || numfds != 0 | |
232 | || !ASYNC_WAIT_CTX_get_changed_fds(waitctx, NULL, &numfds, NULL, | |
233 | &numdelfds) | |
234 | || numfds != 0 | |
235 | || numdelfds != 0 | |
5705e050 MC |
236 | || funcret != 1) { |
237 | fprintf(stderr, "test_ASYNC_get_wait_fd() failed\n"); | |
ff75a257 | 238 | ASYNC_WAIT_CTX_free(waitctx); |
7b9f8f7f | 239 | ASYNC_cleanup_thread(); |
5705e050 MC |
240 | return 0; |
241 | } | |
242 | ||
ff75a257 | 243 | ASYNC_WAIT_CTX_free(waitctx); |
7b9f8f7f | 244 | ASYNC_cleanup_thread(); |
5705e050 MC |
245 | return 1; |
246 | } | |
e8dfb5bf | 247 | |
3cb7c5cf | 248 | static int test_ASYNC_block_pause(void) |
e8dfb5bf MC |
249 | { |
250 | ASYNC_JOB *job = NULL; | |
251 | int funcret; | |
174a74ef | 252 | ASYNC_WAIT_CTX *waitctx = NULL; |
e8dfb5bf | 253 | |
7b9f8f7f | 254 | if ( !ASYNC_init_thread(1, 0) |
ff75a257 MC |
255 | || (waitctx = ASYNC_WAIT_CTX_new()) == NULL |
256 | || ASYNC_start_job(&job, waitctx, &funcret, blockpause, NULL, 0) | |
e8dfb5bf | 257 | != ASYNC_PAUSE |
ff75a257 | 258 | || ASYNC_start_job(&job, waitctx, &funcret, blockpause, NULL, 0) |
e8dfb5bf MC |
259 | != ASYNC_FINISH |
260 | || funcret != 1) { | |
261 | fprintf(stderr, "test_ASYNC_block_pause() failed\n"); | |
ff75a257 | 262 | ASYNC_WAIT_CTX_free(waitctx); |
7b9f8f7f | 263 | ASYNC_cleanup_thread(); |
e8dfb5bf MC |
264 | return 0; |
265 | } | |
266 | ||
ff75a257 | 267 | ASYNC_WAIT_CTX_free(waitctx); |
7b9f8f7f | 268 | ASYNC_cleanup_thread(); |
e8dfb5bf MC |
269 | return 1; |
270 | } | |
271 | ||
5705e050 MC |
272 | int main(int argc, char **argv) |
273 | { | |
c521edc3 MC |
274 | if (!ASYNC_is_capable()) { |
275 | fprintf(stderr, | |
276 | "OpenSSL build is not ASYNC capable - skipping async tests\n"); | |
277 | } else { | |
278 | CRYPTO_set_mem_debug(1); | |
279 | CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); | |
280 | ||
281 | if ( !test_ASYNC_init_thread() | |
282 | || !test_ASYNC_start_job() | |
283 | || !test_ASYNC_get_current_job() | |
284 | || !test_ASYNC_WAIT_CTX_get_all_fds() | |
285 | || !test_ASYNC_block_pause()) { | |
286 | return 1; | |
287 | } | |
5705e050 | 288 | } |
5705e050 MC |
289 | printf("PASS\n"); |
290 | return 0; | |
291 | } |