2 * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
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
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 #define MAGIC_WAIT_FD ((OSSL_ASYNC_FD)99)
47 static int waitfd(void *args)
50 ASYNC_WAIT_CTX *waitctx;
51 job = ASYNC_get_current_job();
54 waitctx = ASYNC_get_wait_ctx(job);
58 /* First case: no fd added or removed */
61 /* Second case: one fd added */
62 if (!ASYNC_WAIT_CTX_set_wait_fd(waitctx, waitctx, MAGIC_WAIT_FD, NULL, NULL))
66 /* Third case: all fd removed */
67 if (!ASYNC_WAIT_CTX_clear_fd(waitctx, waitctx))
71 /* Last case: fd added and immediately removed */
72 if (!ASYNC_WAIT_CTX_set_wait_fd(waitctx, waitctx, MAGIC_WAIT_FD, NULL, NULL))
74 if (!ASYNC_WAIT_CTX_clear_fd(waitctx, waitctx))
80 static int blockpause(void *args)
84 ASYNC_unblock_pause();
90 static int test_ASYNC_init_thread()
92 ASYNC_JOB *job1 = NULL, *job2 = NULL, *job3 = NULL;
93 int funcret1, funcret2, funcret3;
94 ASYNC_WAIT_CTX *waitctx = NULL;
96 if ( !ASYNC_init_thread(2, 0)
97 || (waitctx = ASYNC_WAIT_CTX_new()) == NULL
98 || ASYNC_start_job(&job1, waitctx, &funcret1, only_pause, NULL, 0)
100 || ASYNC_start_job(&job2, waitctx, &funcret2, only_pause, NULL, 0)
102 || ASYNC_start_job(&job3, waitctx, &funcret3, only_pause, NULL, 0)
104 || ASYNC_start_job(&job1, waitctx, &funcret1, only_pause, NULL, 0)
106 || ASYNC_start_job(&job3, waitctx, &funcret3, only_pause, NULL, 0)
108 || ASYNC_start_job(&job2, waitctx, &funcret2, only_pause, NULL, 0)
110 || ASYNC_start_job(&job3, waitctx, &funcret3, only_pause, NULL, 0)
115 fprintf(stderr, "test_ASYNC_init_thread() failed\n");
116 ASYNC_WAIT_CTX_free(waitctx);
117 ASYNC_cleanup_thread();
121 ASYNC_WAIT_CTX_free(waitctx);
122 ASYNC_cleanup_thread();
126 static int test_ASYNC_start_job()
128 ASYNC_JOB *job = NULL;
130 ASYNC_WAIT_CTX *waitctx = NULL;
134 if ( !ASYNC_init_thread(1, 0)
135 || (waitctx = ASYNC_WAIT_CTX_new()) == NULL
136 || ASYNC_start_job(&job, waitctx, &funcret, add_two, NULL, 0)
139 || ASYNC_start_job(&job, waitctx, &funcret, add_two, NULL, 0)
143 fprintf(stderr, "test_ASYNC_start_job() failed\n");
144 ASYNC_WAIT_CTX_free(waitctx);
145 ASYNC_cleanup_thread();
149 ASYNC_WAIT_CTX_free(waitctx);
150 ASYNC_cleanup_thread();
154 static int test_ASYNC_get_current_job()
156 ASYNC_JOB *job = NULL;
158 ASYNC_WAIT_CTX *waitctx = NULL;
162 if ( !ASYNC_init_thread(1, 0)
163 || (waitctx = ASYNC_WAIT_CTX_new()) == NULL
164 || ASYNC_start_job(&job, waitctx, &funcret, save_current, NULL, 0)
167 || ASYNC_start_job(&job, waitctx, &funcret, save_current, NULL, 0)
170 fprintf(stderr, "test_ASYNC_get_current_job() failed\n");
171 ASYNC_WAIT_CTX_free(waitctx);
172 ASYNC_cleanup_thread();
176 ASYNC_WAIT_CTX_free(waitctx);
177 ASYNC_cleanup_thread();
181 static int test_ASYNC_WAIT_CTX_get_all_fds()
183 ASYNC_JOB *job = NULL;
185 ASYNC_WAIT_CTX *waitctx = NULL;
186 OSSL_ASYNC_FD fd = OSSL_BAD_ASYNC_FD, delfd = OSSL_BAD_ASYNC_FD;
187 size_t numfds, numdelfds;
189 if ( !ASYNC_init_thread(1, 0)
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)
194 || !ASYNC_WAIT_CTX_get_all_fds(waitctx, NULL, &numfds)
196 || !ASYNC_WAIT_CTX_get_changed_fds(waitctx, NULL, &numfds, NULL,
200 /* On second run we're expecting one added fd */
201 || ASYNC_start_job(&job, waitctx, &funcret, waitfd, NULL, 0)
203 || !ASYNC_WAIT_CTX_get_all_fds(waitctx, NULL, &numfds)
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,
212 || !ASYNC_WAIT_CTX_get_changed_fds(waitctx, &fd, &numfds, NULL,
214 || fd != MAGIC_WAIT_FD
215 /* On third run we expect one deleted fd */
216 || ASYNC_start_job(&job, waitctx, &funcret, waitfd, NULL, 0)
218 || !ASYNC_WAIT_CTX_get_all_fds(waitctx, NULL, &numfds)
220 || !ASYNC_WAIT_CTX_get_changed_fds(waitctx, NULL, &numfds, NULL,
224 || !ASYNC_WAIT_CTX_get_changed_fds(waitctx, NULL, &numfds, &delfd,
226 || delfd != MAGIC_WAIT_FD
227 /* On last run we are not expecting any wait fd */
228 || ASYNC_start_job(&job, waitctx, &funcret, waitfd, NULL, 0)
230 || !ASYNC_WAIT_CTX_get_all_fds(waitctx, NULL, &numfds)
232 || !ASYNC_WAIT_CTX_get_changed_fds(waitctx, NULL, &numfds, NULL,
237 fprintf(stderr, "test_ASYNC_get_wait_fd() failed\n");
238 ASYNC_WAIT_CTX_free(waitctx);
239 ASYNC_cleanup_thread();
243 ASYNC_WAIT_CTX_free(waitctx);
244 ASYNC_cleanup_thread();
248 static int test_ASYNC_block_pause()
250 ASYNC_JOB *job = NULL;
252 ASYNC_WAIT_CTX *waitctx = NULL;
254 if ( !ASYNC_init_thread(1, 0)
255 || (waitctx = ASYNC_WAIT_CTX_new()) == NULL
256 || ASYNC_start_job(&job, waitctx, &funcret, blockpause, NULL, 0)
258 || ASYNC_start_job(&job, waitctx, &funcret, blockpause, NULL, 0)
261 fprintf(stderr, "test_ASYNC_block_pause() failed\n");
262 ASYNC_WAIT_CTX_free(waitctx);
263 ASYNC_cleanup_thread();
267 ASYNC_WAIT_CTX_free(waitctx);
268 ASYNC_cleanup_thread();
272 int main(int argc, char **argv)
274 if (!ASYNC_is_capable()) {
276 "OpenSSL build is not ASYNC capable - skipping async tests\n");
278 CRYPTO_set_mem_debug(1);
279 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
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()) {