/* 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 <assert.h>
#include <errno.h>
#include <pthread.h>
#include <stdlib.h>
#include <sys/time.h>

#include <gai_misc.h>



#ifndef gai_create_helper_thread
# define gai_create_helper_thread __gai_create_helper_thread

extern inline int
__gai_create_helper_thread (pthread_t *threadp, void *(*tf) (void *),
			    void *arg)
{
  pthread_attr_t attr;

  /* Make sure the thread is created detached.  */
  pthread_attr_init (&attr);
  pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);

  int ret = pthread_create (threadp, &attr, tf, arg);

  (void) pthread_attr_destroy (&attr);
  return ret;
}
#endif


/* Pool of request list entries.  */
static struct requestlist **pool;

/* Number of total and allocated pool entries.  */
static size_t pool_max_size;
static size_t pool_size;

/* We implement a two dimensional array but allocate each row separately.
   The macro below determines how many entries should be used per row.
   It should better be a power of two.  */
#define ENTRIES_PER_ROW	32

/* How many rows we allocate at once.  */
#define ROWS_STEP	8

/* List of available entries.  */
static struct requestlist *freelist;

/* Structure list of all currently processed requests.  */
static struct requestlist *requests;
static struct requestlist *requests_tail;

/* Number of threads currently running.  */
static int nthreads;

/* Number of threads waiting for work to arrive. */
static int idle_thread_count;


/* These are the values used for optimization.  We will probably
   create a funcion to set these values.  */
static struct gaiinit optim =
{
  20,	/* int gai_threads;	Maximal number of threads.  */
  64,	/* int gai_num;		Number of expected simultanious requests. */
  0,
  0,
  0,
  0,
  1,
  0
};


/* Since the list is global we need a mutex protecting it.  */
pthread_mutex_t __gai_requests_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;

/* When you add a request to the list and there are idle threads present,
   you signal this condition variable. When a thread finishes work, it waits
   on this condition variable for a time before it actually exits. */
pthread_cond_t __gai_new_request_notification = PTHREAD_COND_INITIALIZER;


/* Functions to handle request list pool.  */
static struct requestlist *
get_elem (void)
{
  struct requestlist *result;

  if (freelist == NULL)
    {
      struct requestlist *new_row;
      int cnt;

      if (pool_size + 1 >= pool_max_size)
	{
	  size_t new_max_size = pool_max_size + ROWS_STEP;
	  struct requestlist **new_tab;

	  new_tab = (struct requestlist **)
	    realloc (pool, new_max_size * sizeof (struct requestlist *));

	  if (new_tab == NULL)
	    return NULL;

	  pool_max_size = new_max_size;
	  pool = new_tab;
	}

      /* Allocate the new row.  */
      cnt = pool_size == 0 ? optim.gai_num : ENTRIES_PER_ROW;
      new_row = (struct requestlist *) calloc (cnt,
					       sizeof (struct requestlist));
      if (new_row == NULL)
	return NULL;

      pool[pool_size++] = new_row;

      /* Put all the new entries in the freelist.  */
      do
	{
	  new_row->next = freelist;
	  freelist = new_row++;
	}
      while (--cnt > 0);
    }

  result = freelist;
  freelist = freelist->next;

  return result;
}


struct requestlist *
internal_function
__gai_find_request (const struct gaicb *gaicbp)
{
  struct requestlist *runp;

  runp = requests;
  while (runp != NULL)
    if (runp->gaicbp == gaicbp)
      return runp;
    else
      runp = runp->next;

  return NULL;
}


int
internal_function
__gai_remove_request (struct gaicb *gaicbp)
{
  struct requestlist *runp;
  struct requestlist *lastp;

  runp = requests;
  lastp = NULL;
  while (runp != NULL)
    if (runp->gaicbp == gaicbp)
      break;
    else
      {
	lastp = runp;
	runp = runp->next;
      }

  if (runp == NULL)
    /* Not known.  */
    return -1;
  if (runp->running != 0)
    /* Currently handled.  */
    return 1;

  /* Dequeue the request.  */
  if (lastp == NULL)
    requests = runp->next;
  else
    lastp->next = runp->next;
  if (runp == requests_tail)
    requests_tail = lastp;

  return 0;
}


/* The thread handler.  */
static void *handle_requests (void *arg);


/* The main function of the async I/O handling.  It enqueues requests
   and if necessary starts and handles threads.  */
struct requestlist *
internal_function
__gai_enqueue_request (struct gaicb *gaicbp)
{
  struct requestlist *newp;
  struct requestlist *lastp;

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

  /* Get a new element for the waiting list.  */
  newp = get_elem ();
  if (newp == NULL)
    {
      pthread_mutex_unlock (&__gai_requests_mutex);
      __set_errno (EAGAIN);
      return NULL;
    }
  newp->running = 0;
  newp->gaicbp = gaicbp;
  newp->waiting = NULL;
  newp->next = NULL;

  lastp = requests_tail;
  if (requests_tail == NULL)
    requests = requests_tail = newp;
  else
    {
      requests_tail->next = newp;
      requests_tail = newp;
    }

  gaicbp->__return = EAI_INPROGRESS;

  /* See if we need to and are able to create a thread.  */
  if (nthreads < optim.gai_threads && idle_thread_count == 0)
    {
      pthread_t thid;

      newp->running = 1;

      /* Now try to start a thread.  */
      if (gai_create_helper_thread (&thid, handle_requests, newp) == 0)
	/* We managed to enqueue the request.  All errors which can
	   happen now can be recognized by calls to `gai_error'.  */
	++nthreads;
      else
	{
	  if (nthreads == 0)
	    {
	      /* We cannot create a thread in the moment and there is
		 also no thread running.  This is a problem.  `errno' is
		 set to EAGAIN if this is only a temporary problem.  */
	      assert (lastp->next == newp);
	      lastp->next = NULL;
	      requests_tail = lastp;

	      newp->next = freelist;
	      freelist = newp;

	      newp = NULL;
	    }
	  else
	    /* We are not handling the request after all.  */
	    newp->running = 0;
	}
    }

  /* Enqueue the request in the request queue.  */
  if (newp != NULL)
    {
      /* If there is a thread waiting for work, then let it know that we
	 have just given it something to do. */
      if (idle_thread_count > 0)
	pthread_cond_signal (&__gai_new_request_notification);
    }

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

  return newp;
}


static void *
__attribute__ ((noreturn))
handle_requests (void *arg)
{
  struct requestlist *runp = (struct requestlist *) arg;

  do
    {
      /* If runp is NULL, then we were created to service the work queue
	 in general, not to handle any particular request. In that case we
	 skip the "do work" stuff on the first pass, and go directly to the
	 "get work off the work queue" part of this loop, which is near the
	 end. */
      if (runp == NULL)
	pthread_mutex_lock (&__gai_requests_mutex);
      else
	{
	  /* Make the request.  */
	  struct gaicb *req = runp->gaicbp;
	  struct requestlist *srchp;
	  struct requestlist *lastp;

	  req->__return = getaddrinfo (req->ar_name, req->ar_service,
				       req->ar_request, &req->ar_result);

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

	  /* Send the signal to notify about finished processing of the
	     request.  */
	  __gai_notify (runp);

	  /* Now dequeue the current request.  */
	  lastp = NULL;
	  srchp = requests;
	  while (srchp != runp)
	    {
	      lastp = srchp;
	      srchp = srchp->next;
	    }
	  assert (runp->running == 1);

	  if (requests_tail == runp)
	    requests_tail = lastp;
	  if (lastp == NULL)
	    requests = requests->next;
	  else
	    lastp->next = runp->next;

	  /* Free the old element.  */
	  runp->next = freelist;
	  freelist = runp;
	}

      runp = requests;
      while (runp != NULL && runp->running != 0)
	runp = runp->next;

      /* If the runlist is empty, then we sleep for a while, waiting for
	 something to arrive in it. */
      if (runp == NULL && optim.gai_idle_time >= 0)
	{
	  struct timeval now;
	  struct timespec wakeup_time;

	  ++idle_thread_count;
	  gettimeofday (&now, NULL);
	  wakeup_time.tv_sec = now.tv_sec + optim.gai_idle_time;
	  wakeup_time.tv_nsec = now.tv_usec * 1000;
	  if (wakeup_time.tv_nsec >= 1000000000)
	    {
	      wakeup_time.tv_nsec -= 1000000000;
	      ++wakeup_time.tv_sec;
	    }
	  pthread_cond_timedwait (&__gai_new_request_notification,
				  &__gai_requests_mutex, &wakeup_time);
	  --idle_thread_count;
	  runp = requests;
	  while (runp != NULL && runp->running != 0)
	    runp = runp->next;
	}

      if (runp == NULL)
	--nthreads;
      else
	{
	  /* Mark the request as being worked on.  */
	  assert (runp->running == 0);
	  runp->running = 1;

	  /* If we have a request to process, and there's still another in
	     the run list, then we need to either wake up or create a new
	     thread to service the request that is still in the run list. */
	  if (requests != NULL)
	    {
	      /* There are at least two items in the work queue to work on.
		 If there are other idle threads, then we should wake them
		 up for these other work elements; otherwise, we should try
		 to create a new thread. */
	      if (idle_thread_count > 0)
		pthread_cond_signal (&__gai_new_request_notification);
	      else if (nthreads < optim.gai_threads)
		{
		  pthread_t thid;
		  pthread_attr_t attr;

		  /* Make sure the thread is created detached.  */
		  pthread_attr_init (&attr);
		  pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);

		  /* Now try to start a thread. If we fail, no big deal,
		     because we know that there is at least one thread (us)
		     that is working on lookup operations. */
		  if (pthread_create (&thid, &attr, handle_requests, NULL)
		      == 0)
		    ++nthreads;
		}
	    }
	}

      /* Release the mutex.  */
      pthread_mutex_unlock (&__gai_requests_mutex);
    }
  while (runp != NULL);

  pthread_exit (NULL);
}


/* Free allocated resources.  */
libc_freeres_fn (free_res)
{
  size_t row;

  for (row = 0; row < pool_max_size; ++row)
    free (pool[row]);

  free (pool);
}
