/* Event loop machinery for the remote server for GDB.
   Copyright (C) 1999-2002, 2005-2008, 2010-2012 Free Software
   Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>. */

/* Based on src/gdb/event-loop.c.  */

#include "server.h"

#include <sys/types.h>
#include <string.h>
#include <sys/time.h>

#ifdef USE_WIN32API
#include <windows.h>
#include <io.h>
#endif

#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

typedef struct gdb_event gdb_event;
typedef int (event_handler_func) (gdb_fildes_t);

/* Tell create_file_handler what events we are interested in.  */

#define GDB_READABLE	(1<<1)
#define GDB_WRITABLE	(1<<2)
#define GDB_EXCEPTION	(1<<3)

/* Events are queued by calling async_queue_event and serviced later
   on by do_one_event.  An event can be, for instance, a file
   descriptor becoming ready to be read.  Servicing an event simply
   means that the procedure PROC will be called.  We have 2 queues,
   one for file handlers that we listen to in the event loop, and one
   for the file handlers+events that are ready.  The procedure PROC
   associated with each event is always the same (handle_file_event).
   Its duty is to invoke the handler associated with the file
   descriptor whose state change generated the event, plus doing other
   cleanups and such.  */

struct gdb_event
  {
    /* Procedure to call to service this event.  */
    event_handler_func *proc;

    /* File descriptor that is ready.  */
    gdb_fildes_t fd;

    /* Next in list of events or NULL.  */
    struct gdb_event *next_event;
  };

/* Information about each file descriptor we register with the event
   loop.  */

typedef struct file_handler
  {
    /* File descriptor.  */
    gdb_fildes_t fd;

    /* Events we want to monitor.  */
    int mask;

    /* Events that have been seen since the last time.  */
    int ready_mask;

    /* Procedure to call when fd is ready.  */
    handler_func *proc;

    /* Argument to pass to proc.  */
    gdb_client_data client_data;

    /* Was an error detected on this fd?  */
    int error;

    /* Next registered file descriptor.  */
    struct file_handler *next_file;
  }
file_handler;

/* Event queue:

   Events can be inserted at the front of the queue or at the end of
   the queue.  Events will be extracted from the queue for processing
   starting from the head.  Therefore, events inserted at the head of
   the queue will be processed in a last in first out fashion, while
   those inserted at the tail of the queue will be processed in a
   first in first out manner.  All the fields are NULL if the queue is
   empty.  */

static struct
  {
    /* The first pending event.  */
    gdb_event *first_event;

    /* The last pending event.  */
    gdb_event *last_event;
  }
event_queue;

/* Gdb_notifier is just a list of file descriptors gdb is interested
   in.  These are the input file descriptor, and the target file
   descriptor.  Each of the elements in the gdb_notifier list is
   basically a description of what kind of events gdb is interested
   in, for each fd.  */

static struct
  {
    /* Ptr to head of file handler list.  */
    file_handler *first_file_handler;

    /* Masks to be used in the next call to select.  Bits are set in
       response to calls to create_file_handler.  */
    fd_set check_masks[3];

    /* What file descriptors were found ready by select.  */
    fd_set ready_masks[3];

    /* Number of valid bits (highest fd value + 1). (for select) */
    int num_fds;
  }
gdb_notifier;

/* Callbacks are just routines that are executed before waiting for the
   next event.  In GDB this is struct gdb_timer.  We don't need timers
   so rather than copy all that complexity in gdbserver, we provide what
   we need, but we do so in a way that if/when the day comes that we need
   that complexity, it'll be easier to add - replace callbacks with timers
   and use a delta of zero (which is all gdb currently uses timers for anyway).

   PROC will be executed before gdbserver goes to sleep to wait for the
   next event.  */

struct callback_event
  {
    int id;
    callback_handler_func *proc;
    gdb_client_data *data;
    struct callback_event *next;
  };

/* Table of registered callbacks.  */

static struct
  {
    struct callback_event *first;
    struct callback_event *last;

    /* Id of the last callback created.  */
    int num_callbacks;
  }
callback_list;

/* Insert an event object into the gdb event queue.

   EVENT_PTR points to the event to be inserted into the queue.  The
   caller must allocate memory for the event.  It is freed after the
   event has ben handled.  Events in the queue will be processed head
   to tail, therefore, events will be processed first in first
   out.  */

static void
async_queue_event (gdb_event *event_ptr)
{
  /* The event will become the new last_event.  */

  event_ptr->next_event = NULL;
  if (event_queue.first_event == NULL)
    event_queue.first_event = event_ptr;
  else
    event_queue.last_event->next_event = event_ptr;
  event_queue.last_event = event_ptr;
}

/* Process one event.  If an event was processed, 1 is returned
   otherwise 0 is returned.  Scan the queue from head to tail,
   processing therefore the high priority events first, by invoking
   the associated event handler procedure.  */

static int
process_event (void)
{
  gdb_event *event_ptr, *prev_ptr;
  event_handler_func *proc;
  gdb_fildes_t fd;

  /* Look in the event queue to find an event that is ready
     to be processed.  */

  for (event_ptr = event_queue.first_event;
       event_ptr != NULL;
       event_ptr = event_ptr->next_event)
    {
      /* Call the handler for the event.  */

      proc = event_ptr->proc;
      fd = event_ptr->fd;

      /* Let's get rid of the event from the event queue.  We need to
         do this now because while processing the event, since the
         proc function could end up jumping out to the caller of this
         function.  In that case, we would have on the event queue an
         event which has been processed, but not deleted.  */

      if (event_queue.first_event == event_ptr)
	{
	  event_queue.first_event = event_ptr->next_event;
	  if (event_ptr->next_event == NULL)
	    event_queue.last_event = NULL;
	}
      else
	{
	  prev_ptr = event_queue.first_event;
	  while (prev_ptr->next_event != event_ptr)
	    prev_ptr = prev_ptr->next_event;

	  prev_ptr->next_event = event_ptr->next_event;
	  if (event_ptr->next_event == NULL)
	    event_queue.last_event = prev_ptr;
	}
      free (event_ptr);

      /* Now call the procedure associated with the event.  */
      if ((*proc) (fd))
	return -1;
      return 1;
    }

  /* This is the case if there are no event on the event queue.  */
  return 0;
}

/* Append PROC to the callback list.
   The result is the "id" of the callback that can be passed back to
   delete_callback_event.  */

int
append_callback_event (callback_handler_func *proc, gdb_client_data data)
{
  struct callback_event *event_ptr;

  event_ptr = xmalloc (sizeof (*event_ptr));
  event_ptr->id = callback_list.num_callbacks++;
  event_ptr->proc = proc;
  event_ptr->data = data;
  event_ptr->next = NULL;
  if (callback_list.first == NULL)
    callback_list.first = event_ptr;
  if (callback_list.last != NULL)
    callback_list.last->next = event_ptr;
  callback_list.last = event_ptr;
  return event_ptr->id;
}

/* Delete callback ID.
   It is not an error callback ID doesn't exist.  */

void
delete_callback_event (int id)
{
  struct callback_event **p;

  for (p = &callback_list.first; *p != NULL; p = &(*p)->next)
    {
      struct callback_event *event_ptr = *p;

      if (event_ptr->id == id)
	{
	  *p = event_ptr->next;
	  if (event_ptr == callback_list.last)
	    callback_list.last = NULL;
	  free (event_ptr);
	  break;
	}
    }
}

/* Run the next callback.
   The result is 1 if a callback was called and event processing
   should continue, -1 if the callback wants the event loop to exit,
   and 0 if there are no more callbacks.  */

static int
process_callback (void)
{
  struct callback_event *event_ptr;

  event_ptr = callback_list.first;
  if (event_ptr != NULL)
    {
      callback_handler_func *proc = event_ptr->proc;
      gdb_client_data *data = event_ptr->data;

      /* Remove the event before calling PROC,
	 more events may get added by PROC.  */
      callback_list.first = event_ptr->next;
      if (callback_list.first == NULL)
	callback_list.last = NULL;
      free  (event_ptr);
      if ((*proc) (data))
	return -1;
      return 1;
    }

  return 0;
}

/* Add a file handler/descriptor to the list of descriptors we are
   interested in.  FD is the file descriptor for the file/stream to be
   listened to.  MASK is a combination of READABLE, WRITABLE,
   EXCEPTION.  PROC is the procedure that will be called when an event
   occurs for FD.  CLIENT_DATA is the argument to pass to PROC.  */

static void
create_file_handler (gdb_fildes_t fd, int mask, handler_func *proc,
		     gdb_client_data client_data)
{
  file_handler *file_ptr;

  /* Do we already have a file handler for this file? (We may be
     changing its associated procedure).  */
  for (file_ptr = gdb_notifier.first_file_handler;
       file_ptr != NULL;
       file_ptr = file_ptr->next_file)
    if (file_ptr->fd == fd)
      break;

  /* It is a new file descriptor.  Add it to the list.  Otherwise,
     just change the data associated with it.  */
  if (file_ptr == NULL)
    {
      file_ptr = xmalloc (sizeof (*file_ptr));
      file_ptr->fd = fd;
      file_ptr->ready_mask = 0;
      file_ptr->next_file = gdb_notifier.first_file_handler;
      gdb_notifier.first_file_handler = file_ptr;

      if (mask & GDB_READABLE)
	FD_SET (fd, &gdb_notifier.check_masks[0]);
      else
	FD_CLR (fd, &gdb_notifier.check_masks[0]);

      if (mask & GDB_WRITABLE)
	FD_SET (fd, &gdb_notifier.check_masks[1]);
      else
	FD_CLR (fd, &gdb_notifier.check_masks[1]);

      if (mask & GDB_EXCEPTION)
	FD_SET (fd, &gdb_notifier.check_masks[2]);
      else
	FD_CLR (fd, &gdb_notifier.check_masks[2]);

      if (gdb_notifier.num_fds <= fd)
	gdb_notifier.num_fds = fd + 1;
    }

  file_ptr->proc = proc;
  file_ptr->client_data = client_data;
  file_ptr->mask = mask;
}

/* Wrapper function for create_file_handler.  */

void
add_file_handler (gdb_fildes_t fd,
		  handler_func *proc, gdb_client_data client_data)
{
  create_file_handler (fd, GDB_READABLE | GDB_EXCEPTION, proc, client_data);
}

/* Remove the file descriptor FD from the list of monitored fd's:
   i.e. we don't care anymore about events on the FD.  */

void
delete_file_handler (gdb_fildes_t fd)
{
  file_handler *file_ptr, *prev_ptr = NULL;
  int i;

  /* Find the entry for the given file. */

  for (file_ptr = gdb_notifier.first_file_handler;
       file_ptr != NULL;
       file_ptr = file_ptr->next_file)
    if (file_ptr->fd == fd)
      break;

  if (file_ptr == NULL)
    return;

  if (file_ptr->mask & GDB_READABLE)
    FD_CLR (fd, &gdb_notifier.check_masks[0]);
  if (file_ptr->mask & GDB_WRITABLE)
    FD_CLR (fd, &gdb_notifier.check_masks[1]);
  if (file_ptr->mask & GDB_EXCEPTION)
    FD_CLR (fd, &gdb_notifier.check_masks[2]);

  /* Find current max fd.  */

  if ((fd + 1) == gdb_notifier.num_fds)
    {
      gdb_notifier.num_fds--;
      for (i = gdb_notifier.num_fds; i; i--)
	{
	  if (FD_ISSET (i - 1, &gdb_notifier.check_masks[0])
	      || FD_ISSET (i - 1, &gdb_notifier.check_masks[1])
	      || FD_ISSET (i - 1, &gdb_notifier.check_masks[2]))
	    break;
	}
      gdb_notifier.num_fds = i;
    }

  /* Deactivate the file descriptor, by clearing its mask, so that it
     will not fire again.  */

  file_ptr->mask = 0;

  /* Get rid of the file handler in the file handler list.  */
  if (file_ptr == gdb_notifier.first_file_handler)
    gdb_notifier.first_file_handler = file_ptr->next_file;
  else
    {
      for (prev_ptr = gdb_notifier.first_file_handler;
	   prev_ptr->next_file != file_ptr;
	   prev_ptr = prev_ptr->next_file)
	;
      prev_ptr->next_file = file_ptr->next_file;
    }
  free (file_ptr);
}

/* Handle the given event by calling the procedure associated to the
   corresponding file handler.  Called by process_event indirectly,
   through event_ptr->proc.  EVENT_FILE_DESC is file descriptor of the
   event in the front of the event queue.  */

static int
handle_file_event (gdb_fildes_t event_file_desc)
{
  file_handler *file_ptr;
  int mask;

  /* Search the file handler list to find one that matches the fd in
     the event.  */
  for (file_ptr = gdb_notifier.first_file_handler; file_ptr != NULL;
       file_ptr = file_ptr->next_file)
    {
      if (file_ptr->fd == event_file_desc)
	{
	  /* See if the desired events (mask) match the received
	     events (ready_mask).  */

	  if (file_ptr->ready_mask & GDB_EXCEPTION)
	    {
	      fprintf (stderr, "Exception condition detected on fd %s\n",
		       pfildes (file_ptr->fd));
	      file_ptr->error = 1;
	    }
	  else
	    file_ptr->error = 0;
	  mask = file_ptr->ready_mask & file_ptr->mask;

	  /* Clear the received events for next time around.  */
	  file_ptr->ready_mask = 0;

	  /* If there was a match, then call the handler.  */
	  if (mask != 0)
	    {
	      if ((*file_ptr->proc) (file_ptr->error,
				     file_ptr->client_data) < 0)
		return -1;
	    }
	  break;
	}
    }

  return 0;
}

/* Create a file event, to be enqueued in the event queue for
   processing.  The procedure associated to this event is always
   handle_file_event, which will in turn invoke the one that was
   associated to FD when it was registered with the event loop.  */

static gdb_event *
create_file_event (gdb_fildes_t fd)
{
  gdb_event *file_event_ptr;

  file_event_ptr = xmalloc (sizeof (gdb_event));
  file_event_ptr->proc = handle_file_event;
  file_event_ptr->fd = fd;
  return file_event_ptr;
}

/* Called by do_one_event to wait for new events on the monitored file
   descriptors.  Queue file events as they are detected by the poll.
   If there are no events, this function will block in the call to
   select.  Return -1 if there are no files descriptors to monitor,
   otherwise return 0.  */

static int
wait_for_event (void)
{
  file_handler *file_ptr;
  gdb_event *file_event_ptr;
  int num_found = 0;

  /* Make sure all output is done before getting another event.  */
  fflush (stdout);
  fflush (stderr);

  if (gdb_notifier.num_fds == 0)
    return -1;

  gdb_notifier.ready_masks[0] = gdb_notifier.check_masks[0];
  gdb_notifier.ready_masks[1] = gdb_notifier.check_masks[1];
  gdb_notifier.ready_masks[2] = gdb_notifier.check_masks[2];
  num_found = select (gdb_notifier.num_fds,
		      &gdb_notifier.ready_masks[0],
		      &gdb_notifier.ready_masks[1],
		      &gdb_notifier.ready_masks[2],
		      NULL);

  /* Clear the masks after an error from select.  */
  if (num_found == -1)
    {
      FD_ZERO (&gdb_notifier.ready_masks[0]);
      FD_ZERO (&gdb_notifier.ready_masks[1]);
      FD_ZERO (&gdb_notifier.ready_masks[2]);
#ifdef EINTR
      /* Dont print anything if we got a signal, let gdb handle
	 it.  */
      if (errno != EINTR)
	perror_with_name ("select");
#endif
    }

  /* Enqueue all detected file events.  */

  for (file_ptr = gdb_notifier.first_file_handler;
       file_ptr != NULL && num_found > 0;
       file_ptr = file_ptr->next_file)
    {
      int mask = 0;

      if (FD_ISSET (file_ptr->fd, &gdb_notifier.ready_masks[0]))
	mask |= GDB_READABLE;
      if (FD_ISSET (file_ptr->fd, &gdb_notifier.ready_masks[1]))
	mask |= GDB_WRITABLE;
      if (FD_ISSET (file_ptr->fd, &gdb_notifier.ready_masks[2]))
	mask |= GDB_EXCEPTION;

      if (!mask)
	continue;
      else
	num_found--;

      /* Enqueue an event only if this is still a new event for this
	 fd.  */

      if (file_ptr->ready_mask == 0)
	{
	  file_event_ptr = create_file_event (file_ptr->fd);
	  async_queue_event (file_event_ptr);
	}
      file_ptr->ready_mask = mask;
    }

  return 0;
}

/* Start up the event loop.  This is the entry point to the event
   loop.  */

void
start_event_loop (void)
{
  /* Loop until there is nothing to do.  This is the entry point to
     the event loop engine.  If nothing is ready at this time, wait
     for something to happen (via wait_for_event), then process it.
     Return when there are no longer event sources to wait for.  */

  while (1)
    {
      /* Any events already waiting in the queue?  */
      int res = process_event ();

      /* Did the event handler want the event loop to stop?  */
      if (res == -1)
	return;

      if (res)
	continue;

      /* Process any queued callbacks before we go to sleep.  */
      res = process_callback ();

      /* Did the callback want the event loop to stop?  */
      if (res == -1)
	return;

      if (res)
	continue;

      /* Wait for a new event.  If wait_for_event returns -1, we
	 should get out because this means that there are no event
	 sources left.  This will make the event loop stop, and the
	 application exit.  */

      if (wait_for_event () < 0)
	return;
    }

  /* We are done with the event loop.  There are no more event sources
     to listen to.  So we exit gdbserver.  */
}
