Sources Bugzilla – Bug 5508
close does not work on sockets with pending aio
Last modified: 2008-04-07 18:23:56 UTC
The following code demonstrates what I believe is the same issue as
was originally reported, but does so reading from stdin. Once the
aio_read has begun and blocked, aio_cancel is unable to interrupt
it until some data does arrive to be read.
This means it is not possible to destroy the input buffer for a
read that you no longer care to get (or know you will never get)
since if some data does later arrive, the aio_handler function
will still be called. If none ever does, you'll accrue a 'zombie'
thread for the remaining life of the process. Neither of which
is a great situation... so I do hope we can fix this.
$ gcc aio.c -o aio -lrt
/* aio.c */
static void aio_handler(union sigval data)
struct aiocb aio;
aio.aio_fildes = STDIN_FILENO;
aio.aio_offset = 0;
aio.aio_buf = &buf;
aio.aio_nbytes = 1;
aio.aio_reqprio = 0;
aio.aio_sigevent.sigev_notify = SIGEV_THREAD;
aio.aio_sigevent.sigev_notify_function = aio_handler;
aio.aio_sigevent.sigev_notify_attributes = NULL;
aio.aio_sigevent.sigev_value.sival_ptr = NULL;
aio_read( &aio );
if( aio_cancel( STDIN_FILENO, &aio ) == AIO_NOTCANCELED )
I confirmed that the test-case is well formed and reproducing against glibc-cvs.
By checking aio_error() after the sleep() call, we can see that aio_read() is
still EINPROGRESS. And aio_cancel() is indeed returning AIO_NOTCANCELLED.
I tried writing EOF to stdin before the aio_cancel() call but it still returns
AIO_NOTCANCELLED. I also tried LF and the result is the same. So aio_cancel()
can't interrupt aio_read() even after data arrives in stdin.
Is an aio_read() on stdin valid? If so is there a way to terminate the
aio_read() when it is no longer needed? Should there be a way to force an
aio_cancel() on something that will traditionally never finish?
"Which operations are cancelable is implementation-defined."
"The value AIO_NOTCANCELED shall be returned if at least one of the requested
operation(s) cannot be canceled because it is in progress."
That's the case here for the pure userland aio implementation, if an operation
is already in progress as in this case, it is not cancellable.
aio is designed for file I/O. Not everything works as you might like it for
other types of devices. We're not complicating the implementation dramatically
to handle these cases especially since the standard explicitly does not require
it. If you want a better implementation, get sufficient support in the kernel.