=head1 DESCRIPTION
For an overview of how asynchronous operations are implemented in OpenSSL see
-L<ASYNC_start_job(3)>. An ASYNC_WAIT_CTX object represents an asynchronous
+L<ASYNC_start_job(3)>. An B<ASYNC_WAIT_CTX> object represents an asynchronous
"session", i.e. a related set of crypto operations. For example in SSL terms
this would have a one-to-one correspondence with an SSL connection.
-Application code must create an ASYNC_WAIT_CTX using the ASYNC_WAIT_CTX_new()
+Application code must create an B<ASYNC_WAIT_CTX> using the ASYNC_WAIT_CTX_new()
function prior to calling ASYNC_start_job() (see L<ASYNC_start_job(3)>). When
-the job is started it is associated with the ASYNC_WAIT_CTX for the duration of
-that job. An ASYNC_WAIT_CTX should only be used for one ASYNC_JOB at any one
-time, but can be reused after an ASYNC_JOB has finished for a subsequent
-ASYNC_JOB. When the session is complete (e.g. the SSL connection is closed),
-application code cleans up with ASYNC_WAIT_CTX_free().
-
-ASYNC_WAIT_CTXs can have "wait" file descriptors associated with them. Calling
-ASYNC_WAIT_CTX_get_all_fds() and passing in a pointer to an ASYNC_WAIT_CTX in
-the B<ctx> parameter will return the wait file descriptors associated with that
-job in B<*fd>. The number of file descriptors returned will be stored in
-B<*numfds>. It is the caller's responsibility to ensure that sufficient memory
-has been allocated in B<*fd> to receive all the file descriptors. Calling
-ASYNC_WAIT_CTX_get_all_fds() with a NULL B<fd> value will return no file
-descriptors but will still populate B<*numfds>. Therefore application code is
-typically expected to call this function twice: once to get the number of fds,
-and then again when sufficient memory has been allocated. If only one
-asynchronous engine is being used then normally this call will only ever return
-one fd. If multiple asynchronous engines are being used then more could be
-returned.
+the job is started it is associated with the B<ASYNC_WAIT_CTX> for the duration
+of that job. An B<ASYNC_WAIT_CTX> should only be used for one B<ASYNC_JOB> at
+any one time, but can be reused after an B<ASYNC_JOB> has finished for a
+subsequent B<ASYNC_JOB>. When the session is complete (e.g. the SSL connection
+is closed), application code cleans up with ASYNC_WAIT_CTX_free().
+
+B<ASYNC_WAIT_CTX>s can have "wait" file descriptors associated with them.
+Calling ASYNC_WAIT_CTX_get_all_fds() and passing in a pointer to an
+B<ASYNC_WAIT_CTX> in the I<ctx> parameter will return the wait file descriptors
+associated with that job in I<*fd>. The number of file descriptors returned will
+be stored in I<*numfds>. It is the caller's responsibility to ensure that
+sufficient memory has been allocated in I<*fd> to receive all the file
+descriptors. Calling ASYNC_WAIT_CTX_get_all_fds() with a NULL I<fd> value will
+return no file descriptors but will still populate I<*numfds>. Therefore
+application code is typically expected to call this function twice: once to get
+the number of fds, and then again when sufficient memory has been allocated. If
+only one asynchronous engine is being used then normally this call will only
+ever return one fd. If multiple asynchronous engines are being used then more
+could be returned.
The function ASYNC_WAIT_CTX_get_changed_fds() can be used to detect if any fds
-have changed since the last call time ASYNC_start_job() returned an ASYNC_PAUSE
-result (or since the ASYNC_WAIT_CTX was created if no ASYNC_PAUSE result has
-been received). The B<numaddfds> and B<numdelfds> parameters will be populated
-with the number of fds added or deleted respectively. B<*addfd> and B<*delfd>
+have changed since the last call time ASYNC_start_job() returned B<ASYNC_PAUSE>
+(or since the B<ASYNC_WAIT_CTX> was created if no B<ASYNC_PAUSE> result has
+been received). The I<numaddfds> and I<numdelfds> parameters will be populated
+with the number of fds added or deleted respectively. I<*addfd> and I<*delfd>
will be populated with the list of added and deleted fds respectively. Similarly
to ASYNC_WAIT_CTX_get_all_fds() either of these can be NULL, but if they are not
NULL then the caller is responsible for ensuring sufficient memory is allocated.
Implementors of async aware code (e.g. engines) are encouraged to return a
-stable fd for the lifetime of the ASYNC_WAIT_CTX in order to reduce the "churn"
-of regularly changing fds - although no guarantees of this are provided to
-applications.
+stable fd for the lifetime of the B<ASYNC_WAIT_CTX> in order to reduce the
+"churn" of regularly changing fds - although no guarantees of this are provided
+to applications.
Applications can 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
application will have to periodically "poll" the job by attempting to restart it
to see if it is ready to continue.
-Async aware code (e.g. engines) can get the current ASYNC_WAIT_CTX from the job
-via L<ASYNC_get_wait_ctx(3)> and provide a file descriptor to use for waiting
-on by calling ASYNC_WAIT_CTX_set_wait_fd(). Typically this would be done by an
-engine immediately prior to calling ASYNC_pause_job() and not by end user code.
-An existing association with a file descriptor can be obtained using
+Async aware code (e.g. engines) can get the current B<ASYNC_WAIT_CTX> from the
+job via L<ASYNC_get_wait_ctx(3)> and provide a file descriptor to use for
+waiting on by calling ASYNC_WAIT_CTX_set_wait_fd(). Typically this would be done
+by an engine immediately prior to calling ASYNC_pause_job() and not by end user
+code. An existing association with a file descriptor can be obtained using
ASYNC_WAIT_CTX_get_fd() and cleared using ASYNC_WAIT_CTX_clear_fd(). Both of
-these functions requires a B<key> value which is unique to the async aware
+these functions requires a I<key> value which is unique to the async aware
code. This could be any unique value but a good candidate might be the
-B<ENGINE *> for the engine. The B<custom_data> parameter can be any value, and
+B<ENGINE *> for the engine. The I<custom_data> parameter can be any value, and
will be returned in a subsequent call to ASYNC_WAIT_CTX_get_fd(). The
ASYNC_WAIT_CTX_set_wait_fd() function also expects a pointer to a "cleanup"
routine. This can be NULL but if provided will automatically get called when
-the ASYNC_WAIT_CTX is freed, and gives the engine the opportunity to close the
-fd or any other resources. Note: The "cleanup" routine does not get called if
-the fd is cleared directly via a call to ASYNC_WAIT_CTX_clear_fd().
+the B<ASYNC_WAIT_CTX> is freed, and gives the engine the opportunity to close
+the fd or any other resources. Note: The "cleanup" routine does not get called
+if the fd is cleared directly via a call to ASYNC_WAIT_CTX_clear_fd().
An example of typical usage might be an async capable engine. User code would
initiate cryptographic operations. The engine would initiate those operations
file descriptor.
As well as a file descriptor, user code may also be notified via a callback. The
-callback and data pointers are stored within the ASYNC_WAIT_CTX along with an
+callback and data pointers are stored within the B<ASYNC_WAIT_CTX> along with an
additional status field that can be used for the notification of retries from an
engine. This additional method can be used when the user thinks that a file
descriptor is too costly in terms of CPU cycles or in some context where a file
and non-blocking as it will be run in the context of a polling mechanism or an
interrupt.
-ASYNC_WAIT_CTX_get_callback() returns the callback set in the ASYNC_WAIT_CTX
+ASYNC_WAIT_CTX_get_callback() returns the callback set in the B<ASYNC_WAIT_CTX>
structure.
ASYNC_WAIT_CTX_set_status() allows an engine to set the current engine status.
The possible status values are the following:
-ASYNC_STATUS_UNSUPPORTED: The engine does not support the callback mechanism.
-This is the default value. The engine must call ASYNC_WAIT_CTX_set_status() to
-set the status to some value other than ASYNC_STATUS_UNSUPPORTED if it intends
-to enable the callback mechanism.
-ASYNC_STATUS_ERR: The engine has a fatal problem with this request. The user
-code should clean up this session.
-ASYNC_STATUS_OK: The request has been successfully submitted.
-ASYNC_STATUS_EAGAIN: The engine has some problem which will be recovered soon,
-such as a buffer is full, so user code should resume the job.
+
+=over 4
+
+=item B<ASYNC_STATUS_UNSUPPORTED>
+
+The engine does not support the callback mechanism. This is the default value.
+The engine must call ASYNC_WAIT_CTX_set_status() to set the status to some value
+other than B<ASYNC_STATUS_UNSUPPORTED> if it intends to enable the callback
+mechanism.
+
+=item B<ASYNC_STATUS_ERR>
+
+The engine has a fatal problem with this request. The user code should clean up
+this session.
+
+=item B<ASYNC_STATUS_OK>
+
+The request has been successfully submitted.
+
+=item B<ASYNC_STATUS_EAGAIN>
+
+The engine has some problem which will be recovered soon, such as a buffer is
+full, so user code should resume the job.
+
+=back
ASYNC_WAIT_CTX_get_status() allows user code to obtain the current status value.
-If the status is any value other than ASYNC_STATUS_OK then the user code should
-not expect to receive a callback from the engine even if one has been set.
+If the status is any value other than B<ASYNC_STATUS_OK> then the user code
+should not expect to receive a callback from the engine even if one has been
+set.
An example of the usage of the callback method might be the following. User
code would initiate cryptographic operations, and the engine code would dispatch
=head1 RETURN VALUES
-ASYNC_WAIT_CTX_new() returns a pointer to the newly allocated ASYNC_WAIT_CTX or
-NULL on error.
+ASYNC_WAIT_CTX_new() returns a pointer to the newly allocated B<ASYNC_WAIT_CTX>
+or NULL on error.
ASYNC_WAIT_CTX_set_wait_fd, ASYNC_WAIT_CTX_get_fd, ASYNC_WAIT_CTX_get_all_fds,
ASYNC_WAIT_CTX_get_changed_fds, ASYNC_WAIT_CTX_clear_fd,
=head1 DESCRIPTION
-OpenSSL implements asynchronous capabilities through an ASYNC_JOB. This
+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.
-The creation of an ASYNC_JOB is a relatively expensive operation. Therefore, for
-efficiency reasons, jobs can be created up front and reused many times. They are
-held in a pool until they are needed, at which point they are removed from the
-pool, used, and then returned to the pool when the job completes. If the user
-application is multi-threaded, then ASYNC_init_thread() may be called for each
-thread that will initiate asynchronous jobs. Before
+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
+are held in a pool until they are needed, at which point they are removed from
+the pool, used, and then returned to the pool when the job completes. If the
+user application is multi-threaded, then ASYNC_init_thread() may be called for
+each thread that will initiate asynchronous jobs. Before
user code exits per-thread resources need to be cleaned up. This will normally
occur automatically (see L<OPENSSL_init_crypto(3)>) but may be explicitly
initiated by using ASYNC_cleanup_thread(). No asynchronous jobs must be
outstanding for the thread when ASYNC_cleanup_thread() is called. Failing to
ensure this will result in memory leaks.
-The B<max_size> argument limits the number of ASYNC_JOBs that will be held in
-the pool. If B<max_size> is set to 0 then no upper limit is set. When an
-ASYNC_JOB is needed but there are none available in the pool already then one
-will be automatically created, as long as the total of ASYNC_JOBs managed by the
-pool does not exceed B<max_size>. When the pool is first initialised
-B<init_size> ASYNC_JOBs will be created immediately. If ASYNC_init_thread() is
-not called before the pool is first used then it will be called automatically
-with a B<max_size> of 0 (no upper limit) and an B<init_size> of 0 (no ASYNC_JOBs
-created up front).
+The I<max_size> argument limits the number of B<ASYNC_JOB>s that will be held in
+the pool. If I<max_size> is set to 0 then no upper limit is set. When an
+B<ASYNC_JOB> is needed but there are none available in the pool already then one
+will be automatically created, as long as the total of B<ASYNC_JOB>s managed by
+the pool does not exceed I<max_size>. When the pool is first initialised
+I<init_size> B<ASYNC_JOB>s will be created immediately. If ASYNC_init_thread()
+is not called before the pool is first used then it will be called automatically
+with a I<max_size> of 0 (no upper limit) and an I<init_size> of 0 (no
+B<ASYNC_JOB>s created up front).
An asynchronous job is started by calling the ASYNC_start_job() function.
-Initially B<*job> should be NULL. B<ctx> should point to an ASYNC_WAIT_CTX
-object created through the L<ASYNC_WAIT_CTX_new(3)> function. B<ret> should
+Initially I<*job> should be NULL. I<ctx> should point to an B<ASYNC_WAIT_CTX>
+object created through the L<ASYNC_WAIT_CTX_new(3)> function. I<ret> should
point to a location where the return value of the asynchronous function should
-be stored on completion of the job. B<func> represents the function that should
-be started asynchronously. The data pointed to by B<args> and of size B<size>
-will be copied and then passed as an argument to B<func> when the job starts.
+be stored on completion of the job. I<func> represents the function that should
+be started asynchronously. The data pointed to by I<args> and of size I<size>
+will be copied and then passed as an argument to I<func> when the job starts.
ASYNC_start_job will return one of the following values:
=over 4
=item B<ASYNC_PAUSE>
The job was successfully started but was "paused" before it completed (see
-ASYNC_pause_job() below). A handle to the job is placed in B<*job>. Other work
+ASYNC_pause_job() below). A handle to the job is placed in I<*job>. Other work
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 B<*job>. The
-B<func>, B<args> and B<size> parameters will be ignored when restarting a job.
+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.
=item B<ASYNC_FINISH>
-The job completed. B<*job> will be NULL and the return value from B<func> will
-be placed in B<*ret>.
+The job completed. I<*job> will be NULL and the return value from I<func> will
+be placed in I<*ret>.
=back
At any one time there can be a maximum of one job actively running per thread
(you can have many that are paused). ASYNC_get_current_job() can be used to get
-a pointer to the currently executing ASYNC_JOB. If no job is currently executing
-then this will return NULL.
+a pointer to the currently executing B<ASYNC_JOB>. If no job is currently
+executing then this will return NULL.
If executing within the context of a job (i.e. having been called directly or
indirectly by the function "func" passed as an argument to ASYNC_start_job())
then ASYNC_pause_job() will immediately return control to the calling
-application with ASYNC_PAUSE returned from the ASYNC_start_job() call. A
-subsequent call to ASYNC_start_job passing in the relevant ASYNC_JOB in the
-B<*job> parameter will resume execution from the ASYNC_pause_job() call. If
+application with B<ASYNC_PAUSE> returned from the ASYNC_start_job() call. A
+subsequent call to ASYNC_start_job passing in the relevant B<ASYNC_JOB> in the
+I<*job> parameter will resume execution from the ASYNC_pause_job() call. If
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 ASYNC_WAIT_CTX
-for the B<job>. ASYNC_WAIT_CTXs contain two different ways to notify
+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
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 ASYNC_WAIT_CTX is used for
+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
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.
-ASYNC_WAIT_CTXs also have a "callback" mechanism to notify applications. The
+B<ASYNC_WAIT_CTX>s also have a "callback" mechanism to notify applications. The
callback is set by an application, and it will be automatically called when an
engine completes a cryptography operation, so that the application can resume
the paused work flow without polling. An engine could be written to look whether
ASYNC_block_pause() twice then you must call ASYNC_unblock_pause() twice in
order to re-enable pausing. If these functions are called while there is no
currently active job then they have no effect. This functionality can be useful
-to avoid deadlock scenarios. For example during the execution of an ASYNC_JOB an
-application acquires a lock. It then calls some cryptographic function which
+to avoid deadlock scenarios. For example during the execution of an B<ASYNC_JOB>
+an application acquires a lock. It then calls some cryptographic function which
invokes ASYNC_pause_job(). This returns control back to the code that created
-the ASYNC_JOB. If that code then attempts to acquire the same lock before
+the B<ASYNC_JOB>. If that code then attempts to acquire the same lock before
resuming the original job then a deadlock can occur. By calling
ASYNC_block_pause() immediately after acquiring the lock and
ASYNC_unblock_pause() immediately before releasing it then this situation cannot
ASYNC_init_thread returns 1 on success or 0 otherwise.
-ASYNC_start_job returns one of ASYNC_ERR, ASYNC_NO_JOBS, ASYNC_PAUSE or
-ASYNC_FINISH as described above.
+ASYNC_start_job returns one of B<ASYNC_ERR>, B<ASYNC_NO_JOBS>, B<ASYNC_PAUSE> or
+B<ASYNC_FINISH> as described above.
ASYNC_pause_job returns 0 if an error occurred or 1 on success. If called when
-not within the context of an ASYNC_JOB then this is counted as success so 1 is
-returned.
+not within the context of an B<ASYNC_JOB> then this is counted as success so 1
+is returned.
-ASYNC_get_current_job returns a pointer to the currently executing ASYNC_JOB or
-NULL if not within the context of a job.
+ASYNC_get_current_job returns a pointer to the currently executing B<ASYNC_JOB>
+or NULL if not within the context of a job.
-ASYNC_get_wait_ctx() returns a pointer to the ASYNC_WAIT_CTX for the job.
+ASYNC_get_wait_ctx() returns a pointer to the B<ASYNC_WAIT_CTX> for the job.
ASYNC_is_capable() returns 1 if the current platform is async capable or 0
otherwise.
=head1 DESCRIPTION
SSL_waiting_for_async() determines whether an SSL connection is currently
-waiting for asynchronous operations to complete (see the SSL_MODE_ASYNC mode in
-L<SSL_CTX_set_mode(3)>).
+waiting for asynchronous operations to complete (see the B<SSL_MODE_ASYNC> mode
+in L<SSL_CTX_set_mode(3)>).
SSL_get_all_async_fds() returns a list of file descriptor which can be used in a
call to select() or poll() to determine whether the current asynchronous
operation has completed or not. A completed operation will result in data
appearing as "read ready" on the file descriptor (no actual data should be read
-from the file descriptor). This function should only be called if the SSL object
-is currently waiting for asynchronous work to complete (i.e.
-SSL_ERROR_WANT_ASYNC has been received - see L<SSL_get_error(3)>). Typically the
-list will only contain one file descriptor. However if multiple asynchronous
+from the file descriptor). This function should only be called if the B<SSL>
+object is currently waiting for asynchronous work to complete (i.e.
+B<SSL_ERROR_WANT_ASYNC> has been received - see L<SSL_get_error(3)>). Typically
+the list will only contain one file descriptor. However if multiple asynchronous
capable engines are in use then more than one is possible. The number of file
-descriptors returned is stored in B<*numfds> and the file descriptors themselves
-are in B<*fds>. The B<fds> parameter may be NULL in which case no file
-descriptors are returned but B<*numfds> is still populated. It is the callers
-responsibility to ensure sufficient memory is allocated at B<*fds> so typically
-this function is called twice (once with a NULL B<fds> parameter and once
+descriptors returned is stored in I<*numfds> and the file descriptors themselves
+are in I<*fds>. The I<fds> parameter may be NULL in which case no file
+descriptors are returned but I<*numfds> is still populated. It is the callers
+responsibility to ensure sufficient memory is allocated at I<*fds> so typically
+this function is called twice (once with a NULL I<fds> parameter and once
without).
SSL_get_changed_async_fds() returns a list of the asynchronous file descriptors
that have been added and a list that have been deleted since the last
-SSL_ERROR_WANT_ASYNC was received (or since the SSL object was created if no
-SSL_ERROR_WANT_ASYNC has been received). Similar to SSL_get_all_async_fds() it
-is the callers responsibility to ensure that B<*addfd> and B<*delfd> have
+B<SSL_ERROR_WANT_ASYNC> was received (or since the B<SSL> object was created if
+no B<SSL_ERROR_WANT_ASYNC> has been received). Similar to SSL_get_all_async_fds()
+it is the callers responsibility to ensure that I<*addfd> and I<*delfd> have
sufficient memory allocated, although they may be NULL. The number of added fds
-and the number of deleted fds are stored in B<*numaddfds> and B<*numdelfds>
+and the number of deleted fds are stored in I<*numaddfds> and I<*numdelfds>
respectively.
=head1 RETURN VALUES
=head1 DESCRIPTION
-SSL_CTX_set_async_callback() sets an asynchronous callback function. All SSL
-objects generated based on this SSL_CTX will get this callback. If an engine
+SSL_CTX_set_async_callback() sets an asynchronous callback function. All B<SSL>
+objects generated based on this B<SSL_CTX> will get this callback. If an engine
supports the callback mechanism, it will be automatically called if
-SSL_MODE_ASYNC has been set and an asynchronous capable engine completes a
+B<SSL_MODE_ASYNC> has been set and an asynchronous capable engine completes a
cryptography operation to notify the application to resume the paused work flow.
SSL_CTX_set_async_callback_arg() sets the callback argument.
SSL_set_async_callback() allows an application to set a callback in an
-asynchronous SSL object, so that when an engine completes a cryptography
+asynchronous B<SSL> object, so that when an engine completes a cryptography
operation, the callback will be called to notify the application to resume the
paused work flow.
-SSL_set_async_callback_arg() sets an argument for the SSL object when the above
-callback is called.
+SSL_set_async_callback_arg() sets an argument for the B<SSL> object when the
+above callback is called.
SSL_get_async_status() returns the engine status. This function facilitates the
communication from the engine to the application. During an SSL session,
cryptographic operations are dispatched to an engine. The engine status is very
useful for an application to know if the operation has been successfully
dispatched. If the engine does not support this additional callback method,
-"ASYNC_STATUS_UNSUPPORTED" will be returned. See ASYNC_WAIT_CTX_set_status() for
-a description of all of the status values.
+B<ASYNC_STATUS_UNSUPPORTED> will be returned. See ASYNC_WAIT_CTX_set_status()
+for a description of all of the status values.
-An example of the above functions would be the following.
-1. Application sets the async callback and callback data on an SSL connection
+An example of the above functions would be the following:
+
+=over 4
+
+=item 1.
+
+Application sets the async callback and callback data on an SSL connection
by calling SSL_set_async_callback().
-2. Application sets SSL_MODE_ASYNC and makes an asynchronous SSL call
-3. OpenSSL submits the asynchronous request to the engine. If a retry occurs at
-this point then the status within the ASYNC_WAIT_CTX would be set and the async
-callback function would be called (goto Step 7).
-4. The OpenSSL engine pauses the current job and returns, so that the
+
+=item 2.
+
+Application sets B<SSL_MODE_ASYNC> and makes an asynchronous SSL call
+
+=item 3.
+
+OpenSSL submits the asynchronous request to the engine. If a retry occurs at
+this point then the status within the B<ASYNC_WAIT_CTX> would be set and the
+async callback function would be called (goto Step 7).
+
+=item 4.
+
+The OpenSSL engine pauses the current job and returns, so that the
application can continue processing other connections.
-5. At a future point in time (probably via a polling mechanism or via an
+
+=item 5.
+
+At a future point in time (probably via a polling mechanism or via an
interrupt) the engine will become aware that the asynchronous request has
finished processing.
-6. The engine will call the application's callback passing the callback data as
+
+=item 6.
+
+The engine will call the application's callback passing the callback data as
a parameter.
-7. The callback function should then run. Note: it is a requirement that the
+
+=item 7.
+
+The callback function should then run. Note: it is a requirement that the
callback function is small and non-blocking as it will be run in the context of
a polling mechanism or an interrupt.
-8. It is the application's responsibility via the callback function to schedule
+
+=item 8.
+
+It is the application's responsibility via the callback function to schedule
recalling the OpenSSL asynchronous function and to continue processing.
-9. The callback function has the option to check the status returned via
+
+=item 9.
+
+The callback function has the option to check the status returned via
SSL_get_async_status() to determine whether a retry happened instead of the
request being submitted, allowing different processing if required.
+=back
+
=head1 RETURN VALUES
SSL_CTX_set_async_callback(), SSL_set_async_callback(),