glibc/sysdeps/pthread/aio_cancel.c
Ulrich Drepper 5fe14d9670 Update.
* sysdeps/generic/ldsodefs.h (__rtld_global_attribute__): Define.
	(_rtld_global): Use it.

	* sysdeps/gnu/Dist: Remove errlist-compat.c.
	* sysdeps/gnu/Makefile (errlist-compat.c): Build this file in the
	object directory.  Pass all Versions files to the awk script.
	* sysdeps/gnu/errlist-compat.c: Removed.
	* sysdeps/gnu/errlist.awk: Use #errlist-compat comments from the
	first Versions file in the search path which has them.
	Allow multiple errlist symbol versions to have the same count of
	errors.
	* sysdeps/gnu/errlist-compat.awk: Include <errlist-compat.c> instead
	of "errlist-compat.c".
	* sysdeps/gnu/errlist.c: Regenerated.
	* sysdeps/unix/sysv/linux/mips/Versions (libc): Add #errlist-compat
	comments at GLIBC_2.0, GLIBC_2.1 and GLIBC_2.3.
	* sysdeps/unix/sysv/linux/alpha/Versions: Likewise.
	(librt): Add aio_cancel and aio_cancel64 as GLIBC_2.3.
	* sysdeps/unix/sysv/linux/hppa/Versions: Likewise.
	* sysdeps/unix/sysv/linux/sparc/Versions: New file.
	* sysdeps/unix/sysv/linux/alpha/bits/errno.h: New file.
	* sysdeps/unix/sysv/linux/hppa/bits/errno.h (ECANCELED): Define to
	ECANCELLED if not defined by kernel headers.
	* sysdeps/unix/sysv/linux/bits/errno.h: Don't redefine ECANCELED if
	already defined by kernel headers.
	* sysdeps/unix/sysv/linux/sparc/bits/errno.h: New file.
	* sysdeps/pthread/aio_cancel.c: Don't include aio.h and its
	aio_cancel64 renaming hack nor provide weak_alias if aio_cancel
	is a macro.
	* Versions.def (GLIBC_2.3) [librt]: Add.

	* sysdeps/unix/sysv/linux/alpha/pipe.S: New file.

2002-08-28  Ulrich Drepper  <drepper@redhat.com>

	* include/libc-symbols.h [!__ASSEMBLER__] (declare_symbol_1): Add
	missing comma to .type directive.

2002-08-28  Jakub Jelinek  <jakub@redhat.com>
2002-08-29 00:34:10 +00:00

154 lines
3.9 KiB
C

/* Cancel requests associated with given file descriptor.
Copyright (C) 1997, 1998, 2000, 2002 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
/* We use an UGLY hack to prevent gcc from finding us cheating. The
implementation of aio_cancel and aio_cancel64 are identical and so
we want to avoid code duplication by using aliases. But gcc sees
the different parameter lists and prints a warning. We define here
a function so that aio_cancel64 has no prototype. */
#ifndef aio_cancel
#define aio_cancel64 XXX
#include <aio.h>
/* And undo the hack. */
#undef aio_cancel64
#endif
#include <assert.h>
#include <errno.h>
#include "aio_misc.h"
int
aio_cancel (fildes, aiocbp)
int fildes;
struct aiocb *aiocbp;
{
struct requestlist *req = NULL;
int result = AIO_ALLDONE;
/* If fildes is invalid, error. */
if (fcntl (fildes, F_GETFL) < 0)
{
__set_errno (EBADF);
return -1;
}
/* Request the mutex. */
pthread_mutex_lock (&__aio_requests_mutex);
/* We are asked to cancel a specific AIO request. */
if (aiocbp != NULL)
{
/* If the AIO request is not for this descriptor it has no value
to look for the request block. */
if (aiocbp->aio_fildes == fildes)
{
struct requestlist *last = NULL;
req = __aio_find_req_fd (fildes);
if (req == NULL)
{
not_found:
pthread_mutex_unlock (&__aio_requests_mutex);
__set_errno (EINVAL);
return -1;
}
while (req->aiocbp != (aiocb_union *) aiocbp)
{
last = req;
req = req->next_prio;
if (req == NULL)
goto not_found;
}
/* Don't remove the entry if a thread is already working on it. */
if (req->running == allocated)
{
result = AIO_NOTCANCELED;
req = NULL;
}
else
{
/* We can remove the entry. */
__aio_remove_request (last, req, 0);
result = AIO_CANCELED;
req->next_prio = NULL;
}
}
}
else
{
/* Find the beginning of the list of all requests for this
desriptor. */
req = __aio_find_req_fd (fildes);
/* If any request is worked on by a thread it must be the first.
So either we can delete all requests or all but the first. */
if (req != NULL)
{
if (req->running == allocated)
{
struct requestlist *old = req;
req = req->next_prio;
old->next_prio = NULL;
result = AIO_NOTCANCELED;
if (req != NULL)
__aio_remove_request (old, req, 1);
}
else
{
result = AIO_CANCELED;
/* We can remove the entry. */
__aio_remove_request (NULL, req, 1);
}
}
}
/* Mark requests as canceled and send signal. */
while (req != NULL)
{
struct requestlist *old = req;
assert (req->running == yes || req->running == queued);
req->aiocbp->aiocb.__error_code = ECANCELED;
req->aiocbp->aiocb.__return_value = -1;
__aio_notify (req);
req = req->next_prio;
__aio_free_request (old);
}
/* Release the mutex. */
pthread_mutex_unlock (&__aio_requests_mutex);
return result;
}
#ifndef aio_cancel
weak_alias (aio_cancel, aio_cancel64)
#endif