mirror of
https://github.com/openssl/openssl.git
synced 2025-02-17 14:32:04 +08:00
ASYNC_start_job: more readable documentation for handling ASYNC* APIs
Signed-off-by: Hubert Kario <hkario@redhat.com> Reviewed-by: Matt Caswell <matt@openssl.org> Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com> Reviewed-by: Neil Horman <nhorman@openssl.org> (Merged from https://github.com/openssl/openssl/pull/23941)
This commit is contained in:
parent
e53a7ccd11
commit
36e2fbe38b
@ -38,7 +38,8 @@ ASYNC_stack_alloc_fn, ASYNC_stack_free_fn, ASYNC_set_mem_functions, ASYNC_get_me
|
||||
OpenSSL implements asynchronous capabilities through an B<ASYNC_JOB>. This
|
||||
represents code that can be started and executes until some event occurs. At
|
||||
that point the code can be paused and control returns to user code until some
|
||||
subsequent event indicates that the job can be resumed.
|
||||
subsequent event indicates that the job can be resumed. It's OpenSSL
|
||||
specific implementation of cooperative multitasking.
|
||||
|
||||
The creation of an B<ASYNC_JOB> is a relatively expensive operation. Therefore,
|
||||
for efficiency reasons, jobs can be created up front and reused many times. They
|
||||
@ -91,7 +92,8 @@ can be performed (if desired) and the job restarted at a later time. To restart
|
||||
a job call ASYNC_start_job() again passing the job handle in I<*job>. The
|
||||
I<func>, I<args> and I<size> parameters will be ignored when restarting a job.
|
||||
When restarting a job ASYNC_start_job() B<must> be called from the same thread
|
||||
that the job was originally started from.
|
||||
that the job was originally started from. B<ASYNC_WAIT_CTX> is used to
|
||||
know when a job is ready to be restarted.
|
||||
|
||||
=item B<ASYNC_FINISH>
|
||||
|
||||
@ -115,13 +117,15 @@ ASYNC_pause_job() is called whilst not within the context of a job then no
|
||||
action is taken and ASYNC_pause_job() returns immediately.
|
||||
|
||||
ASYNC_get_wait_ctx() can be used to get a pointer to the B<ASYNC_WAIT_CTX>
|
||||
for the I<job>. B<ASYNC_WAIT_CTX>s contain two different ways to notify
|
||||
for the I<job> (see L<ASYNC_WAIT_CTX_new(3)>).
|
||||
B<ASYNC_WAIT_CTX>s contain two different ways to notify
|
||||
applications that a job is ready to be resumed. One is a "wait" file
|
||||
descriptor, and the other is a "callback" mechanism.
|
||||
|
||||
The "wait" file descriptor associated with B<ASYNC_WAIT_CTX> is used for
|
||||
applications to wait for the file descriptor to be ready for "read" using a
|
||||
system function call such as select or poll (being ready for "read" indicates
|
||||
system function call such as select(2) or poll(2) (being ready for "read"
|
||||
indicates
|
||||
that the job should be resumed). If no file descriptor is made available then
|
||||
an application will have to periodically "poll" the job by attempting to restart
|
||||
it to see if it is ready to continue.
|
||||
@ -236,6 +240,13 @@ The following example demonstrates how to use most of the core async APIs:
|
||||
msg = (unsigned char *)arg;
|
||||
printf("Passed in message is: %s\n", msg);
|
||||
|
||||
/*
|
||||
* Create a way to inform the calling thread when this job is ready
|
||||
* to resume, in this example we're using file descriptors.
|
||||
* For offloading the task to an asynchronous ENGINE it's not necessary,
|
||||
* the ENGINE should handle that internally.
|
||||
*/
|
||||
|
||||
if (pipe(pipefds) != 0) {
|
||||
printf("Failed to create pipe\n");
|
||||
return 0;
|
||||
@ -250,17 +261,23 @@ The following example demonstrates how to use most of the core async APIs:
|
||||
pipefds[0], wptr, cleanup);
|
||||
|
||||
/*
|
||||
* Normally some external event would cause this to happen at some
|
||||
* Normally some external event (like a network read being ready,
|
||||
* disk access being finished, or some hardware offload operation
|
||||
* completing) would cause this to happen at some
|
||||
* later point - but we do it here for demo purposes, i.e.
|
||||
* immediately signalling that the job is ready to be woken up after
|
||||
* we return to main via ASYNC_pause_job().
|
||||
*/
|
||||
write(pipefds[1], &buf, 1);
|
||||
|
||||
/* Return control back to main */
|
||||
/*
|
||||
* Return control back to main just before calling a blocking
|
||||
* method. The main thread will wait until pipefds[0] is ready
|
||||
* for reading before returning control to this thread.
|
||||
*/
|
||||
ASYNC_pause_job();
|
||||
|
||||
/* Clear the wake signal */
|
||||
/* Perform the blocking call (it won't block with this example code) */
|
||||
read(pipefds[0], &buf, 1);
|
||||
|
||||
printf ("Resumed the job after a pause\n");
|
||||
@ -300,7 +317,9 @@ The following example demonstrates how to use most of the core async APIs:
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* Wait for the job to be woken */
|
||||
/* Get the file descriptor we can use to wait for the job
|
||||
* to be ready to be woken up
|
||||
*/
|
||||
printf("Waiting for the job to be woken up\n");
|
||||
|
||||
if (!ASYNC_WAIT_CTX_get_all_fds(ctx, NULL, &numfds)
|
||||
@ -311,6 +330,8 @@ The following example demonstrates how to use most of the core async APIs:
|
||||
ASYNC_WAIT_CTX_get_all_fds(ctx, &waitfd, &numfds);
|
||||
FD_ZERO(&waitfdset);
|
||||
FD_SET(waitfd, &waitfdset);
|
||||
|
||||
/* Wait for the job to be ready for wakeup */
|
||||
select(waitfd + 1, &waitfdset, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user