Standard preamble:
========================================================================
..
.... Set up some character translations and predefined strings. \*(-- will
give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
double quote, and \*(R" will give a right double quote. \*(C+ will
give a nicer C++. Capital omega is used to do unbreakable dashes and
therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
nothing in troff, for use with C<>.
.tr \(*W- . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\}
Escape single quotes in literal strings from groff's Unicode transform.
If the F register is >0, we'll generate index entries on stderr for
titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
entries marked with X<> in POD. Of course, you'll have to process the
output yourself in some meaningful fashion.
Avoid warning from groff about undefined register 'F'.
.. .nr rF 0 . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF Fear. Run. Save yourself. No user-serviceable parts.
. \" fudge factors for nroff and troff . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] .\} . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents . \" corrections for vroff . \" for low resolution devices (crt and lpr) \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} ========================================================================
Title "ASYNC_WAIT_CTX_NEW 3ossl"
way too many mistakes in technical documents.
Application code must create an \s-1ASYNC_WAIT_CTX\s0 using the ASYNC_WAIT_CTX_new() function prior to calling ASYNC_start_job() (see ASYNC_start_job\|(3)). When the job is started it is associated with the \s-1ASYNC_WAIT_CTX\s0 for the duration of that job. An \s-1ASYNC_WAIT_CTX\s0 should only be used for one \s-1ASYNC_JOB\s0 at any one time, but can be reused after an \s-1ASYNC_JOB\s0 has finished for a subsequent \s-1ASYNC_JOB\s0. When the session is complete (e.g. the \s-1SSL\s0 connection is closed), application code cleans up with ASYNC_WAIT_CTX_free().
\fB\s-1ASYNC_WAIT_CTX\s0s can have \*(L"wait\*(R" file descriptors associated with them. Calling ASYNC_WAIT_CTX_get_all_fds() and passing in a pointer to an \fB\s-1ASYNC_WAIT_CTX\s0 in the ctx parameter will return the wait file descriptors associated with that job in *fd. The number of file descriptors returned will be stored in *numfds. It is the caller's responsibility to ensure that sufficient memory has been allocated in *fd to receive all the file descriptors. Calling ASYNC_WAIT_CTX_get_all_fds() with a \s-1NULL\s0 fd value will return no file descriptors but will still populate *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 \s-1ASYNC_PAUSE\s0 (or since the \s-1ASYNC_WAIT_CTX\s0 was created if no \s-1ASYNC_PAUSE\s0 result has been received). The numaddfds and numdelfds parameters will be populated with the number of fds added or deleted respectively. *addfd and *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 \s-1NULL,\s0 but if they are not \s-1NULL\s0 then the caller is responsible for ensuring sufficient memory is allocated.
Implementers of async aware code (e.g. engines) are encouraged to return a stable fd for the lifetime of the \s-1ASYNC_WAIT_CTX\s0 in order to reduce the \*(L"churn\*(R" of regularly changing fds - although no guarantees of this are provided to applications.
Applications can wait for the file descriptor to be ready for \*(L"read\*(R" using a system function call such as select or poll (being ready for \*(L"read\*(R" indicates that the job should be resumed). If no file descriptor is made available then an application will have to periodically \*(L"poll\*(R" 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 \s-1ASYNC_WAIT_CTX\s0 from the job via 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 \fBASYNC_WAIT_CTX_get_fd() and cleared using ASYNC_WAIT_CTX_clear_fd(). Both of these functions requires a key value which is unique to the async aware code. This could be any unique value but a good candidate might be the \fB\s-1ENGINE\s0 * for the engine. The custom_data parameter can be any value, and will be returned in a subsequent call to ASYNC_WAIT_CTX_get_fd(). The \fBASYNC_WAIT_CTX_set_wait_fd() function also expects a pointer to a \*(L"cleanup\*(R" routine. This can be \s-1NULL\s0 but if provided will automatically get called when the \s-1ASYNC_WAIT_CTX\s0 is freed, and gives the engine the opportunity to close the fd or any other resources. Note: The \*(L"cleanup\*(R" 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 asynchronously and then call ASYNC_WAIT_CTX_set_wait_fd() followed by \fBASYNC_pause_job() to return control to the user code. The user code can then perform other tasks or wait for the job to be ready by calling \*(L"select\*(R" or other similar function on the wait file descriptor. The engine can signal to the user code that the job should be resumed by making the wait file descriptor \*(L"readable\*(R". Once resumed the engine should clear the wake signal on the wait 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 \s-1ASYNC_WAIT_CTX\s0 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 \s-1CPU\s0 cycles or in some context where a file descriptor is not appropriate.
\fBASYNC_WAIT_CTX_set_callback() sets the callback and the callback argument. The callback will be called to notify user code when an engine completes a cryptography operation. It is a requirement that the callback function is small and nonblocking as it will be run in the context of a polling mechanism or an interrupt.
\fBASYNC_WAIT_CTX_get_callback() returns the callback set in the \s-1ASYNC_WAIT_CTX\s0 structure.
\fBASYNC_WAIT_CTX_set_status() allows an engine to set the current engine status. The possible status values are the following:
\fBASYNC_WAIT_CTX_get_status() allows user code to obtain the current status value. If the status is any value other than \s-1ASYNC_STATUS_OK\s0 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 this operation to hardware, and if the dispatch is successful, then the engine code would call ASYNC_pause_job() to return control to the user code. After that, user code can perform other tasks. When the hardware completes the operation, normally it is detected by a polling function or an interrupt, as the user code set a callback by calling ASYNC_WAIT_CTX_set_callback() previously, then the registered callback will be called.
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, ASYNC_WAIT_CTX_set_callback, ASYNC_WAIT_CTX_get_callback and ASYNC_WAIT_CTX_set_status all return 1 on success or 0 on error. \fBASYNC_WAIT_CTX_get_status() returns the engine status.
\fBASYNC_WAIT_CTX_set_callback(), ASYNC_WAIT_CTX_get_callback(), \fBASYNC_WAIT_CTX_set_status(), and ASYNC_WAIT_CTX_get_status() were added in OpenSSL 3.0.
Licensed under the Apache License 2.0 (the \*(L"License\*(R"). You may not use this file except in compliance with the License. You can obtain a copy in the file \s-1LICENSE\s0 in the source distribution or at <https://www.openssl.org/source/license.html>.