2 * Copyright 2015-2020 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the Apache License 2.0 (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
16 #include <openssl/async.h>
17 #include <openssl/crypto.h>
20 static ASYNC_JOB
*currjob
= NULL
;
22 static int only_pause(void *args
)
29 static int add_two(void *args
)
38 static int save_current(void *args
)
40 currjob
= ASYNC_get_current_job();
46 static int change_deflt_libctx(void *args
)
48 OSSL_LIB_CTX
*libctx
= OSSL_LIB_CTX_new();
49 OSSL_LIB_CTX
*oldctx
, *tmpctx
;
55 oldctx
= OSSL_LIB_CTX_set0_default(libctx
);
58 /* Check the libctx is set up as we expect */
59 tmpctx
= OSSL_LIB_CTX_set0_default(oldctx
);
63 /* Set it back again to continue to use our own libctx */
64 oldctx
= OSSL_LIB_CTX_set0_default(libctx
);
67 /* Check the libctx is set up as we expect */
68 tmpctx
= OSSL_LIB_CTX_set0_default(oldctx
);
74 OSSL_LIB_CTX_free(libctx
);
79 #define MAGIC_WAIT_FD ((OSSL_ASYNC_FD)99)
80 static int waitfd(void *args
)
83 ASYNC_WAIT_CTX
*waitctx
;
84 job
= ASYNC_get_current_job();
87 waitctx
= ASYNC_get_wait_ctx(job
);
91 /* First case: no fd added or removed */
94 /* Second case: one fd added */
95 if (!ASYNC_WAIT_CTX_set_wait_fd(waitctx
, waitctx
, MAGIC_WAIT_FD
, NULL
, NULL
))
99 /* Third case: all fd removed */
100 if (!ASYNC_WAIT_CTX_clear_fd(waitctx
, waitctx
))
104 /* Last case: fd added and immediately removed */
105 if (!ASYNC_WAIT_CTX_set_wait_fd(waitctx
, waitctx
, MAGIC_WAIT_FD
, NULL
, NULL
))
107 if (!ASYNC_WAIT_CTX_clear_fd(waitctx
, waitctx
))
113 static int blockpause(void *args
)
117 ASYNC_unblock_pause();
123 static int test_ASYNC_init_thread(void)
125 ASYNC_JOB
*job1
= NULL
, *job2
= NULL
, *job3
= NULL
;
126 int funcret1
, funcret2
, funcret3
;
127 ASYNC_WAIT_CTX
*waitctx
= NULL
;
129 if ( !ASYNC_init_thread(2, 0)
130 || (waitctx
= ASYNC_WAIT_CTX_new()) == NULL
131 || ASYNC_start_job(&job1
, waitctx
, &funcret1
, only_pause
, NULL
, 0)
133 || ASYNC_start_job(&job2
, waitctx
, &funcret2
, only_pause
, NULL
, 0)
135 || ASYNC_start_job(&job3
, waitctx
, &funcret3
, only_pause
, NULL
, 0)
137 || ASYNC_start_job(&job1
, waitctx
, &funcret1
, only_pause
, NULL
, 0)
139 || ASYNC_start_job(&job3
, waitctx
, &funcret3
, only_pause
, NULL
, 0)
141 || ASYNC_start_job(&job2
, waitctx
, &funcret2
, only_pause
, NULL
, 0)
143 || ASYNC_start_job(&job3
, waitctx
, &funcret3
, only_pause
, NULL
, 0)
148 fprintf(stderr
, "test_ASYNC_init_thread() failed\n");
149 ASYNC_WAIT_CTX_free(waitctx
);
150 ASYNC_cleanup_thread();
154 ASYNC_WAIT_CTX_free(waitctx
);
155 ASYNC_cleanup_thread();
159 static int test_callback(void *arg
)
161 printf("callback test pass\n");
165 static int test_ASYNC_callback_status(void)
167 ASYNC_WAIT_CTX
*waitctx
= NULL
;
169 ASYNC_callback_fn get_callback
;
173 if ( !ASYNC_init_thread(1, 0)
174 || (waitctx
= ASYNC_WAIT_CTX_new()) == NULL
175 || ASYNC_WAIT_CTX_set_callback(waitctx
, test_callback
, (void*)&set_arg
)
177 || ASYNC_WAIT_CTX_get_callback(waitctx
, &get_callback
, &get_arg
)
179 || test_callback
!= get_callback
180 || get_arg
!= (void*)&set_arg
181 || (*get_callback
)(get_arg
) != 1
182 || ASYNC_WAIT_CTX_set_status(waitctx
, set_status
) != 1
183 || set_status
!= ASYNC_WAIT_CTX_get_status(waitctx
)) {
184 fprintf(stderr
, "test_ASYNC_callback_status() failed\n");
185 ASYNC_WAIT_CTX_free(waitctx
);
186 ASYNC_cleanup_thread();
190 ASYNC_WAIT_CTX_free(waitctx
);
191 ASYNC_cleanup_thread();
196 static int test_ASYNC_start_job(void)
198 ASYNC_JOB
*job
= NULL
;
200 ASYNC_WAIT_CTX
*waitctx
= NULL
;
204 if ( !ASYNC_init_thread(1, 0)
205 || (waitctx
= ASYNC_WAIT_CTX_new()) == NULL
206 || ASYNC_start_job(&job
, waitctx
, &funcret
, add_two
, NULL
, 0)
209 || ASYNC_start_job(&job
, waitctx
, &funcret
, add_two
, NULL
, 0)
213 fprintf(stderr
, "test_ASYNC_start_job() failed\n");
214 ASYNC_WAIT_CTX_free(waitctx
);
215 ASYNC_cleanup_thread();
219 ASYNC_WAIT_CTX_free(waitctx
);
220 ASYNC_cleanup_thread();
224 static int test_ASYNC_get_current_job(void)
226 ASYNC_JOB
*job
= NULL
;
228 ASYNC_WAIT_CTX
*waitctx
= NULL
;
232 if ( !ASYNC_init_thread(1, 0)
233 || (waitctx
= ASYNC_WAIT_CTX_new()) == NULL
234 || ASYNC_start_job(&job
, waitctx
, &funcret
, save_current
, NULL
, 0)
237 || ASYNC_start_job(&job
, waitctx
, &funcret
, save_current
, NULL
, 0)
240 fprintf(stderr
, "test_ASYNC_get_current_job() failed\n");
241 ASYNC_WAIT_CTX_free(waitctx
);
242 ASYNC_cleanup_thread();
246 ASYNC_WAIT_CTX_free(waitctx
);
247 ASYNC_cleanup_thread();
251 static int test_ASYNC_WAIT_CTX_get_all_fds(void)
253 ASYNC_JOB
*job
= NULL
;
255 ASYNC_WAIT_CTX
*waitctx
= NULL
;
256 OSSL_ASYNC_FD fd
= OSSL_BAD_ASYNC_FD
, delfd
= OSSL_BAD_ASYNC_FD
;
257 size_t numfds
, numdelfds
;
259 if ( !ASYNC_init_thread(1, 0)
260 || (waitctx
= ASYNC_WAIT_CTX_new()) == NULL
261 /* On first run we're not expecting any wait fds */
262 || ASYNC_start_job(&job
, waitctx
, &funcret
, waitfd
, NULL
, 0)
264 || !ASYNC_WAIT_CTX_get_all_fds(waitctx
, NULL
, &numfds
)
266 || !ASYNC_WAIT_CTX_get_changed_fds(waitctx
, NULL
, &numfds
, NULL
,
270 /* On second run we're expecting one added fd */
271 || ASYNC_start_job(&job
, waitctx
, &funcret
, waitfd
, NULL
, 0)
273 || !ASYNC_WAIT_CTX_get_all_fds(waitctx
, NULL
, &numfds
)
275 || !ASYNC_WAIT_CTX_get_all_fds(waitctx
, &fd
, &numfds
)
276 || fd
!= MAGIC_WAIT_FD
277 || (fd
= OSSL_BAD_ASYNC_FD
, 0) /* Assign to something else */
278 || !ASYNC_WAIT_CTX_get_changed_fds(waitctx
, NULL
, &numfds
, NULL
,
282 || !ASYNC_WAIT_CTX_get_changed_fds(waitctx
, &fd
, &numfds
, NULL
,
284 || fd
!= MAGIC_WAIT_FD
285 /* On third run we expect one deleted fd */
286 || ASYNC_start_job(&job
, waitctx
, &funcret
, waitfd
, NULL
, 0)
288 || !ASYNC_WAIT_CTX_get_all_fds(waitctx
, NULL
, &numfds
)
290 || !ASYNC_WAIT_CTX_get_changed_fds(waitctx
, NULL
, &numfds
, NULL
,
294 || !ASYNC_WAIT_CTX_get_changed_fds(waitctx
, NULL
, &numfds
, &delfd
,
296 || delfd
!= MAGIC_WAIT_FD
297 /* On last run we are not expecting any wait fd */
298 || ASYNC_start_job(&job
, waitctx
, &funcret
, waitfd
, NULL
, 0)
300 || !ASYNC_WAIT_CTX_get_all_fds(waitctx
, NULL
, &numfds
)
302 || !ASYNC_WAIT_CTX_get_changed_fds(waitctx
, NULL
, &numfds
, NULL
,
307 fprintf(stderr
, "test_ASYNC_get_wait_fd() failed\n");
308 ASYNC_WAIT_CTX_free(waitctx
);
309 ASYNC_cleanup_thread();
313 ASYNC_WAIT_CTX_free(waitctx
);
314 ASYNC_cleanup_thread();
318 static int test_ASYNC_block_pause(void)
320 ASYNC_JOB
*job
= NULL
;
322 ASYNC_WAIT_CTX
*waitctx
= NULL
;
324 if ( !ASYNC_init_thread(1, 0)
325 || (waitctx
= ASYNC_WAIT_CTX_new()) == NULL
326 || ASYNC_start_job(&job
, waitctx
, &funcret
, blockpause
, NULL
, 0)
328 || ASYNC_start_job(&job
, waitctx
, &funcret
, blockpause
, NULL
, 0)
331 fprintf(stderr
, "test_ASYNC_block_pause() failed\n");
332 ASYNC_WAIT_CTX_free(waitctx
);
333 ASYNC_cleanup_thread();
337 ASYNC_WAIT_CTX_free(waitctx
);
338 ASYNC_cleanup_thread();
342 static int test_ASYNC_start_job_ex(void)
344 ASYNC_JOB
*job
= NULL
;
346 ASYNC_WAIT_CTX
*waitctx
= NULL
;
347 OSSL_LIB_CTX
*libctx
= OSSL_LIB_CTX_new();
348 OSSL_LIB_CTX
*oldctx
, *tmpctx
, *globalctx
;
351 if (libctx
== NULL
) {
353 "test_ASYNC_start_job_ex() failed to create libctx\n");
357 globalctx
= oldctx
= OSSL_LIB_CTX_set0_default(libctx
);
359 if ((waitctx
= ASYNC_WAIT_CTX_new()) == NULL
360 || ASYNC_start_job(&job
, waitctx
, &funcret
, change_deflt_libctx
,
364 "test_ASYNC_start_job_ex() failed to start job\n");
368 /* Reset the libctx temporarily to find out what it is*/
369 tmpctx
= OSSL_LIB_CTX_set0_default(oldctx
);
370 oldctx
= OSSL_LIB_CTX_set0_default(tmpctx
);
371 if (tmpctx
!= libctx
) {
373 "test_ASYNC_start_job_ex() failed - unexpected libctx\n");
377 if (ASYNC_start_job(&job
, waitctx
, &funcret
, change_deflt_libctx
, NULL
, 0)
380 "test_ASYNC_start_job_ex() - restarting job failed\n");
384 /* Reset the libctx and continue with the global default libctx */
385 tmpctx
= OSSL_LIB_CTX_set0_default(oldctx
);
386 if (tmpctx
!= libctx
) {
388 "test_ASYNC_start_job_ex() failed - unexpected libctx\n");
392 if (ASYNC_start_job(&job
, waitctx
, &funcret
, change_deflt_libctx
, NULL
, 0)
396 "test_ASYNC_start_job_ex() - finishing job failed\n");
400 /* Reset the libctx temporarily to find out what it is*/
401 tmpctx
= OSSL_LIB_CTX_set0_default(libctx
);
402 OSSL_LIB_CTX_set0_default(tmpctx
);
403 if (tmpctx
!= globalctx
) {
405 "test_ASYNC_start_job_ex() failed - global libctx check failed\n");
411 ASYNC_WAIT_CTX_free(waitctx
);
412 OSSL_LIB_CTX_free(libctx
);
416 int main(int argc
, char **argv
)
418 if (!ASYNC_is_capable()) {
420 "OpenSSL build is not ASYNC capable - skipping async tests\n");
422 if (!test_ASYNC_init_thread()
423 || !test_ASYNC_callback_status()
424 || !test_ASYNC_start_job()
425 || !test_ASYNC_get_current_job()
426 || !test_ASYNC_WAIT_CTX_get_all_fds()
427 || !test_ASYNC_block_pause()
428 || !test_ASYNC_start_job_ex()) {