/* Cancel requests associated with given file descriptor.
   Copyright (C) 1997-2018 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, see
   <http://www.gnu.org/licenses/>.  */


/* 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 <fcntl.h>

#include <aio_misc.h>


int
aio_cancel (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)
	{
	  pthread_mutex_unlock (&__aio_requests_mutex);
	  __set_errno (EINVAL);
	  return -1;
	}
      else if (aiocbp->__error_code == EINPROGRESS)
	{
	  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
