summaryrefslogtreecommitdiffstats
path: root/doc
diff options
context:
space:
mode:
authorHubert Kario <hkario@redhat.com>2024-03-22 17:41:35 +0100
committerNeil Horman <nhorman@openssl.org>2024-04-02 10:45:30 -0400
commit36e2fbe38b21ce6d4a6bfde3b6deb692ca32fa39 (patch)
treea2a508e2fa00a2e62a20879f756569b4ff442fd4 /doc
parente53a7ccd11c6aef965c50335187a473540819390 (diff)
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)
Diffstat (limited to 'doc')
-rw-r--r--doc/man3/ASYNC_start_job.pod37
1 files changed, 29 insertions, 8 deletions
diff --git a/doc/man3/ASYNC_start_job.pod b/doc/man3/ASYNC_start_job.pod
index e1e42bce4c..2a5428e410 100644
--- a/doc/man3/ASYNC_start_job.pod
+++ b/doc/man3/ASYNC_start_job.pod
@@ -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);
}