aio_read() — Asynchronous read from a socket

Standards

Standards / Extensions C or C++ Dependencies

Single UNIX Specification, Version 2
Single UNIX Specification, Version 3

both

OS/390 V2R7

Format

#define _XOPEN_SOURCE 500
#include <aio.h>

int aio_read(struct aiocb *aiocbp);

General description

The aio_read() function initiates an asynchronous read operation as described by the aiocb structure (the asynchronous I/O control block).

The aiocbp argument points to the aiocb structure. This structure contains the following members:
aio_fildes
file descriptor
aio_offset
file offset
aio_buf
location of buffer
aio_nbytes
length of transfer
aio_reqprio
request priority offset
aio_sigevent
signal number and value
aio_lio_opcode
operation to be performed

The operation reads up to aio_nbytes from the socket or file associated with aio_fildes into the buffer pointed to by aio_buf. The call to aio_read() returns when the request has been initiated or queued to the file or device (even when the data cannot be delivered immediately).

Asynchronous I/O is currently only supported for sockets. The aio_offset field may be set but it will be ignored.

With a stream socket an asynchronous read may be completed when the first packet of data arrives and the application may have to issue additional reads, either asynchronously or synchronously, to get all the data it wants. A datagram socket has message boundaries and the operation will not complete until an entire message has arrived.

The aiocbp value may be used as an argument to aio_error() and aio_return() functions in order to determine the error status and return status, respectively, of the asynchronous operation. While the operation is proceeding, the error status retrieved by aio_error() is EINPROGRESS; the return status retrieved by aio_return() however is unpredictable.

If an error condition is encountered during the queueing, the function call returns without having initiated or queued the request.

When the operation completes asynchronously the program can be notified by a signal as specified in the aio_sigevent structure. It is significantly more efficient to receive these notifications with sigwaitinfo() or sigtimedwait() than to let them drive a signal handler. At this time the return and error status will have been updated to reflect the outcome of the operation. The sigevent structure's notification function fields are not supported. If a signal is not desired the program can occasionally poll the aiocb with aio_error() until the result is no longer EINPROGRESS.

Be aware that the operation may complete, and the signal handler may be delivered, before control returns from the call to aio_read(). Even when the operation does complete this quickly the return value from the call to aio_read() will be zero, reflecting the queueing of the I/O request not the results of the I/O itself.

An asynchronous operation may be canceled with aio_cancel() before its completion. Canceled operations complete with an error status of ECANCELED and any specified signal will be delivered. Due to timing, the operation may still complete naturally, either successfully or unsuccessfully, before it can be canceled by aio_cancel().

If the file descriptor of this operation is closed, the operation will be deleted if it has not completed or is not just about to complete. Signals specified for deleted operations will not be delivered. Close() will wait for asynchronous operations in progress for the descriptor to be deleted or completed.

You may use aio_suspend() to wait for the completion of asynchronous operations.

Sockets must be in blocking state or the operation may fail with EWOULDBLOCK.

If the control block pointed by aiocbp or the buffer pointed to by aio_buf becomes an illegal address before the asynchronous I/O completion, then the behavior of aio_read() is unpredictable.

If the thread that makes the aio_read() request terminates before the I/O completes the aiocb structure will still be updated with the return and error status, and any specified signal will be delivered to the process in which the thread was running. If thread related storage was used on the request the results are quite unpredictable.

Simultaneous asynchronous operations using the same aiocbp, asynchronous operations using a non-valid aiocbp, or any system action, that changes the process memory space while asynchronous I/O is outstanding to that address range, will produce unpredictable results

Simultaneous aio_read() operations on the same socket should not be done in general. With stream sockets, the I/O complete notifications may not be delivered in the same order as the bytes to which they refer, and so the byte stream may appear out of order. With UDP sockets, each datagram will complete one aio_read() operation, but you should not use multiple aio_reads for UDP sockets because this can cause significantly more system overhead as data arrives than a single outstanding request would.

There are several sockets oriented extensions to asynchronous I/O available with the BPX1AIO callable service, such as asynchronous accept(), asynchronous accept_and_recv(), asynchronous forms of all five pairs of read and write type operations, and receiving I/O completion notifications via an ECB, exit program, or through a message queue. The <aio.h> header contains all the structure fields, constants, and prototypes necessary to use BPX1AIO from a C program. These extensions are exposed when the _AIO_OS390 feature test macro is defined. The BPX1AIO stub resides in SYS1.CSSLIB and must be bound with your program. For a more detailed description of asynchronous I/O services, see BPX1AIO in z/OS UNIX System Services Programming: Assembler Callable Services Reference.

The aio_lio_opcode field is set to LIO_READ by the function aio_read().

_POSIX-PRIORITIZED_IO is not supported. The aio_reqprio field may be set but it will be ignored.

_POSIX_SYNCHRONIZED_IO is not supported.

Returned value

If successful, aio_read() returns 0 to the calling process.

If unsuccessful, aio_read() returns -1 and sets errno to one of the following values:
Error Code
Description
EAGAIN
The requested asynchronous I/O operation was not queued due to system resource limitations.
ENOSYS
The file associated with aio_fildes does not support the aio_read() function.
Each of the following conditions may be detected synchronously at the time of the call to aio_read(), or asynchronously. If any of the conditions below are detected synchronously, aio_read() returns -1 and sets the errno to the corresponding value. If any of the conditions below are detected asynchronously, the return status of the asynchronous operation is set to -1, and the error status of the asynchronous operation will be set to the corresponding value.
Error Code
Description
EBADF
The aio_fildes argument is not a valid file descriptor open for reading.
EINVAL
aio_sigevent contains an non-valid value.
EWOULDBLOCK
The file associated with aio_fildes is in nonblocking state and there is no data available.
In the case where the aio_read() function successfully queues the I/O operation but the operation is subsequently canceled or encounters an error, the return status of the asynchronous operations is set to -1, and the error status of the asynchronous operation will be set to the error status normally set by the read() function call, or to the following value:
Error Code
Description
ECANCELED
The requested I/O was canceled before the I/O completed due to an explicit call to aio_cancel().

Related information