/* Copyright (C) 2001-2014 Free Software Foundation, Inc.
   This file is part of the GNU C Library.
   Contributed by Ulrich Drepper <drepper@redhat.com>, 2001.

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

#include <errno.h>
#include <netdb.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>

#include <gai_misc.h>


/* We need this special structure to handle asynchronous I/O.  */
struct async_waitlist
  {
    int counter;
    struct sigevent sigev;
    struct waitlist list[0];
  };


int
getaddrinfo_a (int mode, struct gaicb *list[], int ent, struct sigevent *sig)
{
  struct sigevent defsigev;
  struct requestlist *requests[ent];
  int cnt;
  volatile int total = 0;
  int result = 0;

  /* Check arguments.  */
  if (mode != GAI_WAIT && mode != GAI_NOWAIT)
    {
      __set_errno (EINVAL);
      return EAI_SYSTEM;
    }

  if (sig == NULL)
    {
      defsigev.sigev_notify = SIGEV_NONE;
      sig = &defsigev;
    }

  /* Request the mutex.  */
  pthread_mutex_lock (&__gai_requests_mutex);

  /* Now we can enqueue all requests.  Since we already acquired the
     mutex the enqueue function need not do this.  */
  for (cnt = 0; cnt < ent; ++cnt)
    if (list[cnt] != NULL)
      {
	requests[cnt] = __gai_enqueue_request (list[cnt]);

	if (requests[cnt] != NULL)
	  /* Successfully enqueued.  */
	  ++total;
	else
	  /* Signal that we've seen an error.  `errno' and the error code
	     of the gaicb will tell more.  */
	  result = EAI_SYSTEM;
      }
    else
      requests[cnt] = NULL;

  if (total == 0)
    {
      /* We don't have anything to do except signalling if we work
	 asynchronously.  */

      /* Release the mutex.  We do this before raising a signal since the
	 signal handler might do a `siglongjmp' and then the mutex is
	 locked forever.  */
      pthread_mutex_unlock (&__gai_requests_mutex);

      if (mode == GAI_NOWAIT)
	__gai_notify_only (sig,
			   sig->sigev_notify == SIGEV_SIGNAL ? getpid () : 0);

      return result;
    }
  else if (mode == GAI_WAIT)
    {
#ifndef DONT_NEED_GAI_MISC_COND
      pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
#endif
      struct waitlist waitlist[ent];
      int oldstate;

      total = 0;
      for (cnt = 0; cnt < ent; ++cnt)
	if (requests[cnt] != NULL)
	  {
#ifndef DONT_NEED_GAI_MISC_COND
	    waitlist[cnt].cond = &cond;
#endif
	    waitlist[cnt].next = requests[cnt]->waiting;
	    waitlist[cnt].counterp = &total;
	    waitlist[cnt].sigevp = NULL;
	    waitlist[cnt].caller_pid = 0;	/* Not needed.  */
	    requests[cnt]->waiting = &waitlist[cnt];
	    ++total;
	  }

      /* Since `pthread_cond_wait'/`pthread_cond_timedwait' are cancelation
	 points we must be careful.  We added entries to the waiting lists
	 which we must remove.  So defer cancelation for now.  */
      pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &oldstate);

      while (total > 0)
	{
#ifdef DONT_NEED_GAI_MISC_COND
	  int not_used __attribute__ ((unused));
	  GAI_MISC_WAIT (not_used, total, NULL, 1);
#else
	  pthread_cond_wait (&cond, &__gai_requests_mutex);
#endif
	}

      /* Now it's time to restore the cancelation state.  */
      pthread_setcancelstate (oldstate, NULL);

#ifndef DONT_NEED_GAI_MISC_COND
      /* Release the conditional variable.  */
      if (pthread_cond_destroy (&cond) != 0)
	/* This must never happen.  */
	abort ();
#endif
    }
  else
    {
      struct async_waitlist *waitlist;

      waitlist = (struct async_waitlist *)
	malloc (sizeof (struct async_waitlist)
		+ (ent * sizeof (struct waitlist)));

      if (waitlist == NULL)
	result = EAI_AGAIN;
      else
	{
	  pid_t caller_pid = sig->sigev_notify == SIGEV_SIGNAL ? getpid () : 0;
	  total = 0;

	  for (cnt = 0; cnt < ent; ++cnt)
	    if (requests[cnt] != NULL)
	      {
#ifndef DONT_NEED_GAI_MISC_COND
		waitlist->list[cnt].cond = NULL;
#endif
		waitlist->list[cnt].next = requests[cnt]->waiting;
		waitlist->list[cnt].counterp = &waitlist->counter;
		waitlist->list[cnt].sigevp = &waitlist->sigev;
		waitlist->list[cnt].caller_pid = caller_pid;
		requests[cnt]->waiting = &waitlist->list[cnt];
		++total;
	      }

	  waitlist->counter = total;
	  waitlist->sigev = *sig;
	}
    }

  /* Release the mutex.  */
  pthread_mutex_unlock (&__gai_requests_mutex);

  return result;
}
