HP-UX Reference (11i v2 07/12) - 2 System Calls (vol 5)
a
aio_reap(2) aio_reap(2)
The use of aio_reap() in an application should not be mixed with the older
aio_return() or
aio_error() functions. Mixing of the two methods of IO collection will result in undefined behavior and
possible data loss.
The timeout parameter must be either NULL or point to a
timespec structure that has a timeout time
specified. If a
NULL pointer is specified, then no timeout handling is performed and
aio_reap() blocks
until
waitfor AIO requests are available. If timeout
points to a zero-value timespec structure,
aio_reap() returns immediately after checking for any completed AIO requests (behaves similar to
poll()).
The aio_reap() function call returns to the calling process in any of the following conditions:
1. the specified number of completed requests are available, or
2. the timeout time has elapsed, or
3. a signal has interrupted the function, or
4. an error situation is detected.
In all cases, aio_reap() will attempt to collect as many IOs as possible at the time of its return, even if
less than waitfor IOs have completed when a timeout, signal, or error interrupts aio_reap().If
more than waitfor IOs have completed, aio_reap() will attempt to return up to nent IOs. As a
result, the value of
completed_count
should be checked after all calls to aio_reap() (regardless of
its return value or errno status).
Light-Weight Polling Mode
When called with all
NULL arguments (except for completed_count
), aio_reap() will simply
return in
completed_count
the number of IOs that have completed and are ready for collection.
In light-weight polling mode,
aio_reap() is implemented to execute quickly, without requiring the cost
of a regular system call. This allows applications to poll for completed IOs without incurring significant
costs.
(Note: all releases will provide this polling functionality, but the actual mechanism by which lightweight
polling is implemented is release specific. However, it should in all cases be faster than a regular system
call.)
Multithreading Notes
The aio_reap() interface is completely thread safe, but there are three issues that multithreaded appli-
cations should be aware of:
The first is starvation. When multiple threads concurrently perform aio_reap() calls, there is no
guarantee that completed I/Os will be distributed fairly across the calls. For example, if 50
I/Os are issued
and two threads call
aio_reap() with waitfor=25 and nent=50, there is no guarantee that both
threads will collect any particular number of I/Os. In fact, one possible outcome is that the first thread’s
call to aio_reap() will collect all 50 I/Os, and the second thread will have none to collect. Mul-
tithreaded applications should take this possibility into consideration, and make appropriate use of
timeout values to prevent unbounded waits in starvation situations.
Another related issue is that when threads perform aio_reap() calls, they can collect I/Os issued by any
thread in the process (not just the calling thread). As an example, if thread A and thread B each issue 10
I/Os, and then each calls aio_reap() with waitfor=10 and nent=10, no assumptions can be made
about which I/Os each call to aio_reap() will collect. Thread A’s call to aio_reap() might collect all
10 of thread A’s I/Os, all 10 of thread B’s I/Os, or any mixture of the two. The only guaranteed behavior is
that the first call to aio_reap() will collect the first 10 I/Os to complete.
The third issue is that it is possible for multiple threads to disrupt execution of aio_reap() if they cor-
rupt the arguments to aio_reap() during its execution. For example, problems can arise if one thread
of a multithreaded application invalidates the completed_count pointer used by another thread con-
currently executing a call to
aio_reap() (for example, by freeing or mlocking the corresponding
memory). If this happens, it is possible for aio_reap() to complete I/Os and fill in
aio_completion_t structures but then be unable to update completed_count
. In this case
aio_reap() will return with errno set to [EFAULT], but will have no way to let the application know
how many IOs it has completed. The completed I/Os will be stored in list, but the application will not be
able to know how many I/Os have completed, so it is possible to lose I/Os in this case. Multithreaded appli-
cations must avoid this situation.
HP-UX 11i Version 2: December 2007 Update − 2 − Hewlett-Packard Company 45