This is the mail archive of the
libc-alpha@sources.redhat.com
mailing list for the glibc project.
[patch] aio_*() posix compliance (update)
- From: Amos Waterland <apw at us dot ibm dot com>
- To: libc-alpha at sources dot redhat dot com
- Cc: Tom Gall <tom_gall at vnet dot ibm dot com>
- Date: Fri, 28 Jun 2002 15:23:14 -0500
- Subject: [patch] aio_*() posix compliance (update)
There is a small problem with aio_cancel() in the case:
aio_cancel (fd, &cb), where cb refers to a completed operation on fd.
It returns -1 with errno == 22 (EINVAL).
The case: aio_cancel (fd, NULL), where fd has a completed operation on
it, returns AIO_ALLDONE, which is per the standard[1]:
The value AIO_ALLDONE is returned if all of the operations have
already completed.
Here is the output of the below test program:
% ./test0034
0 1 2 3 4 5 6 7
./test0034: aio_cancel(done,&cb) ret: -1, errno: 22: Operation not
permitted
I have added a patch and a regression test for the problem to the
cleaned-up combination patch that I posted last week. It is available
here:
http://www-124.ibm.com/developer/opensource/linux/patches/?patch_id=466
Here just the new patch:
---- Begin Patch ----
Index: sysdeps/pthread/aio_cancel.c
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/pthread/aio_cancel.c,v
retrieving revision 1.2
diff -u -r1.2 aio_cancel.c
--- sysdeps/pthread/aio_cancel.c 6 Jul 2001 04:56:02 -0000 1.2
+++ sysdeps/pthread/aio_cancel.c 28 Jun 2002 19:47:48 -0000
@@ -61,8 +61,7 @@
{
not_found:
pthread_mutex_unlock (&__aio_requests_mutex);
- __set_errno (EINVAL);
- return -1;
+ return AIO_ALLDONE;
}
while (req->aiocbp != (aiocb_union *) aiocbp)
---- End Patch ----
---- Begin test0034.c ----
/* Show that aio_cancel() does not return AIO_ALLDONE if passed completed.
* Amos Waterland <apw@us.ibm.com>
* 26 June 2002
*/
#include <aio.h>
#include <error.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int
main (int argc, char *argv[])
{
int result = 0;
{
const int BYTES = 8;
int i, r, fd;
char buff[BYTES];
char name[] = "/tmp/aio7.XXXXXX";
struct aiocb cb;
if ((fd = mkstemp (name)) < 0)
error (1, errno, "creating temp file");
if (unlink (name))
error (1, errno, "unlinking temp file");
if (write (fd, "01234567", BYTES) != BYTES)
error (1, errno, "writing to temp file");
cb.aio_fildes = fd;
cb.aio_offset = 0;
cb.aio_buf = buff;
cb.aio_nbytes = BYTES;
cb.aio_reqprio = 0;
cb.aio_sigevent.sigev_notify = SIGEV_NONE;
if ((r = aio_read (&cb)))
error (1, errno, "reading from file");
while (aio_error (&(cb)) == EINPROGRESS)
usleep (10);
for (i = 0; i < BYTES; i++)
printf ("%c ", buff[i]);
printf ("\n");
/* The read is completed, so aio_cancel() should return AIO_ALLDONE. */
errno = 0;
r = aio_cancel (fd, &cb);
if (r != AIO_ALLDONE)
{
error (0, 1, "aio_cancel(done,&cb) ret: %i, errno: %i", r, errno);
result++;
}
}
exit (result);
}
---- End test0034.c ----
[1] http://www.opengroup.org/onlinepubs/007904975/functions/aio_cancel.html