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. Cheers, Ron $ gcc aio.c -o aio -lrt $ ./aio aww poo. /* aio.c */ #include <stdio.h> #include <unistd.h> #include <aio.h> static void aio_handler(union sigval data) { printf("aio read\n"); } int main() { struct aiocb aio; char buf; 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 ); sleep(1); if( aio_cancel( STDIN_FILENO, &aio ) == AIO_NOTCANCELED ) printf("aww poo.\n"); else printf("woo hoo!\n"); return 0; }
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? Regards, Carlos
http://www.opengroup.org/onlinepubs/009695399/functions/aio_cancel.html "Which operations are cancelable is implementation-defined." and "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.