This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]