/* Event loop machinery for GDB, the GNU debugger.
   Copyright (C) 1999-2022 Free Software Foundation, Inc.
   Written by Elena Zannoni <ezannoni@cygnus.com> of Cygnus Solutions.

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

#include "gdbsupport/common-defs.h"
#include "gdbsupport/event-loop.h"

#include <chrono>

#ifdef HAVE_POLL
#if defined (HAVE_POLL_H)
#include <poll.h>
#elif defined (HAVE_SYS_POLL_H)
#include <sys/poll.h>
#endif
#endif

#include <sys/types.h>
#include "gdbsupport/gdb_sys_time.h"
#include "gdbsupport/gdb_select.h"

/* See event-loop.h.  */

debug_event_loop_kind debug_event_loop;

/* Tell create_file_handler what events we are interested in.
   This is used by the select version of the event loop.  */

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

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

struct file_handler
{
  /* File descriptor.  */
  int fd;

  /* Events we want to monitor: POLLIN, etc.  */
  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;

  /* User-friendly name of this handler.  */
  std::string name;

  /* If set, this file descriptor is used for a user interface.  */
  bool is_ui;

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

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

#ifdef HAVE_POLL
/* Do we use poll or select?  Some systems have poll, but then it's
   not useable with all kinds of files.  We probe that whenever a new
   file handler is added.  */
static bool use_poll = true;
#endif

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

/* Gdb_notifier is just a list of file descriptors gdb is interested in.
   These are the input file descriptor, and the target file
   descriptor.  We have two flavors of the notifier, one for platforms
   that have the POLL function, the other for those that don't, and
   only support SELECT.  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;

    /* Next file handler to handle, for the select variant.  To level
       the fairness across event sources, we serve file handlers in a
       round-robin-like fashion.  The number and order of the polled
       file handlers may change between invocations, but this is good
       enough.  */
    file_handler *next_file_handler;

#ifdef HAVE_POLL
    /* Ptr to array of pollfd structures.  */
    struct pollfd *poll_fds;

    /* Next file descriptor to handle, for the poll variant.  To level
       the fairness across event sources, we poll the file descriptors
       in a round-robin-like fashion.  The number and order of the
       polled file descriptors may change between invocations, but
       this is good enough.  */
    int next_poll_fds_index;

    /* Timeout in milliseconds for calls to poll().  */
    int poll_timeout;
#endif

    /* 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 file descriptors to monitor (for poll).  */
    /* Number of valid bits (highest fd value + 1) (for select).  */
    int num_fds;

    /* Time structure for calls to select().  */
    struct timeval select_timeout;

    /* Flag to tell whether the timeout should be used.  */
    int timeout_valid;
  }
gdb_notifier;

/* Structure associated with a timer.  PROC will be executed at the
   first occasion after WHEN.  */
struct gdb_timer
  {
    std::chrono::steady_clock::time_point when;
    int timer_id;
    struct gdb_timer *next;
    timer_handler_func *proc;	    /* Function to call to do the work.  */
    gdb_client_data client_data;    /* Argument to async_handler_func.  */
  };

/* List of currently active timers.  It is sorted in order of
   increasing timers.  */
static struct
  {
    /* Pointer to first in timer list.  */
    struct gdb_timer *first_timer;

    /* Id of the last timer created.  */
    int num_timers;
  }
timer_list;

static void create_file_handler (int fd, int mask, handler_func *proc,
				 gdb_client_data client_data,
				 std::string &&name, bool is_ui);
static int gdb_wait_for_event (int);
static int update_wait_timeout (void);
static int poll_timers (void);

/* Process one high level event.  If nothing is ready at this time,
   wait for something to happen (via gdb_wait_for_event), then process
   it.  Returns >0 if something was done otherwise returns <0 (this
   can happen if there are no event sources to wait for).  */

int
gdb_do_one_event (void)
{
  static int event_source_head = 0;
  const int number_of_sources = 3;
  int current = 0;

  /* First let's see if there are any asynchronous signal handlers
     that are ready.  These would be the result of invoking any of the
     signal handlers.  */
  if (invoke_async_signal_handlers ())
    return 1;

  /* To level the fairness across event sources, we poll them in a
     round-robin fashion.  */
  for (current = 0; current < number_of_sources; current++)
    {
      int res;

      switch (event_source_head)
	{
	case 0:
	  /* Are any timers that are ready?  */
	  res = poll_timers ();
	  break;
	case 1:
	  /* Are there events already waiting to be collected on the
	     monitored file descriptors?  */
	  res = gdb_wait_for_event (0);
	  break;
	case 2:
	  /* Are there any asynchronous event handlers ready?  */
	  res = check_async_event_handlers ();
	  break;
	default:
	  internal_error (__FILE__, __LINE__,
			  "unexpected event_source_head %d",
			  event_source_head);
	}

      event_source_head++;
      if (event_source_head == number_of_sources)
	event_source_head = 0;

      if (res > 0)
	return 1;
    }

  /* Block waiting for a new event.  If gdb_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 (gdb_wait_for_event (1) < 0)
    return -1;

  /* If gdb_wait_for_event has returned 1, it means that one event has
     been handled.  We break out of the loop.  */
  return 1;
}

/* See event-loop.h  */

void
add_file_handler (int fd, handler_func *proc, gdb_client_data client_data,
		  std::string &&name, bool is_ui)
{
#ifdef HAVE_POLL
  if (use_poll)
    {
      struct pollfd fds;

      /* Check to see if poll () is usable.  If not, we'll switch to
	 use select.  This can happen on systems like
	 m68k-motorola-sys, `poll' cannot be used to wait for `stdin'.
	 On m68k-motorola-sysv, tty's are not stream-based and not
	 `poll'able.  */
      fds.fd = fd;
      fds.events = POLLIN;
      if (poll (&fds, 1, 0) == 1 && (fds.revents & POLLNVAL))
	use_poll = false;
    }
  if (use_poll)
    {
      create_file_handler (fd, POLLIN, proc, client_data, std::move (name),
			   is_ui);
    }
  else
#endif /* HAVE_POLL */
    create_file_handler (fd, GDB_READABLE | GDB_EXCEPTION,
			 proc, client_data, std::move (name), is_ui);
}

/* Helper for add_file_handler.

   For the poll case, MASK is a combination (OR) of POLLIN,
   POLLRDNORM, POLLRDBAND, POLLPRI, POLLOUT, POLLWRNORM, POLLWRBAND:
   these are the events we are interested in.  If any of them occurs,
   proc should be called.

   For the select case, 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 (int fd, int mask, handler_func * proc,
		     gdb_client_data client_data, std::string &&name,
		     bool is_ui)
{
  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 = new file_handler;
      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;

#ifdef HAVE_POLL
      if (use_poll)
	{
	  gdb_notifier.num_fds++;
	  if (gdb_notifier.poll_fds)
	    gdb_notifier.poll_fds =
	      (struct pollfd *) xrealloc (gdb_notifier.poll_fds,
					  (gdb_notifier.num_fds
					   * sizeof (struct pollfd)));
	  else
	    gdb_notifier.poll_fds =
	      XNEW (struct pollfd);
	  (gdb_notifier.poll_fds + gdb_notifier.num_fds - 1)->fd = fd;
	  (gdb_notifier.poll_fds + gdb_notifier.num_fds - 1)->events = mask;
	  (gdb_notifier.poll_fds + gdb_notifier.num_fds - 1)->revents = 0;
	}
      else
#endif /* HAVE_POLL */
	{
	  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;
  file_ptr->name = std::move (name);
  file_ptr->is_ui = is_ui;
}

/* Return the next file handler to handle, and advance to the next
   file handler, wrapping around if the end of the list is
   reached.  */

static file_handler *
get_next_file_handler_to_handle_and_advance (void)
{
  file_handler *curr_next;

  /* The first time around, this is still NULL.  */
  if (gdb_notifier.next_file_handler == NULL)
    gdb_notifier.next_file_handler = gdb_notifier.first_file_handler;

  curr_next = gdb_notifier.next_file_handler;
  gdb_assert (curr_next != NULL);

  /* Advance.  */
  gdb_notifier.next_file_handler = curr_next->next_file;
  /* Wrap around, if necessary.  */
  if (gdb_notifier.next_file_handler == NULL)
    gdb_notifier.next_file_handler = gdb_notifier.first_file_handler;

  return curr_next;
}

/* 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 (int 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;

#ifdef HAVE_POLL
  if (use_poll)
    {
      int j;
      struct pollfd *new_poll_fds;

      /* Create a new poll_fds array by copying every fd's information
	 but the one we want to get rid of.  */

      new_poll_fds = (struct pollfd *) 
	xmalloc ((gdb_notifier.num_fds - 1) * sizeof (struct pollfd));

      for (i = 0, j = 0; i < gdb_notifier.num_fds; i++)
	{
	  if ((gdb_notifier.poll_fds + i)->fd != fd)
	    {
	      (new_poll_fds + j)->fd = (gdb_notifier.poll_fds + i)->fd;
	      (new_poll_fds + j)->events = (gdb_notifier.poll_fds + i)->events;
	      (new_poll_fds + j)->revents
		= (gdb_notifier.poll_fds + i)->revents;
	      j++;
	    }
	}
      xfree (gdb_notifier.poll_fds);
      gdb_notifier.poll_fds = new_poll_fds;
      gdb_notifier.num_fds--;
    }
  else
#endif /* HAVE_POLL */
    {
      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;

  /* If this file handler was going to be the next one to be handled,
     advance to the next's next, if any.  */
  if (gdb_notifier.next_file_handler == file_ptr)
    {
      if (file_ptr->next_file == NULL
	  && file_ptr == gdb_notifier.first_file_handler)
	gdb_notifier.next_file_handler = NULL;
      else
	get_next_file_handler_to_handle_and_advance ();
    }

  /* 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;
    }

  delete file_ptr;
}

/* Handle the given event by calling the procedure associated to the
   corresponding file handler.  */

static void
handle_file_event (file_handler *file_ptr, int ready_mask)
{
  int mask;

  /* See if the desired events (mask) match the received events
     (ready_mask).  */

#ifdef HAVE_POLL
  if (use_poll)
    {
      int error_mask;

      /* With poll, the ready_mask could have any of three events set
	 to 1: POLLHUP, POLLERR, POLLNVAL.  These events cannot be
	 used in the requested event mask (events), but they can be
	 returned in the return mask (revents).  We need to check for
	 those event too, and add them to the mask which will be
	 passed to the handler.  */

      /* POLLHUP means EOF, but can be combined with POLLIN to
	 signal more data to read.  */
      error_mask = POLLHUP | POLLERR | POLLNVAL;
      mask = ready_mask & (file_ptr->mask | error_mask);

      if ((mask & (POLLERR | POLLNVAL)) != 0)
	{
	  /* Work in progress.  We may need to tell somebody
	     what kind of error we had.  */
	  if (mask & POLLERR)
	    warning (_("Error detected on fd %d"), file_ptr->fd);
	  if (mask & POLLNVAL)
	    warning (_("Invalid or non-`poll'able fd %d"),
		     file_ptr->fd);
	  file_ptr->error = 1;
	}
      else
	file_ptr->error = 0;
    }
  else
#endif /* HAVE_POLL */
    {
      if (ready_mask & GDB_EXCEPTION)
	{
	  warning (_("Exception condition detected on fd %d"),
		   file_ptr->fd);
	  file_ptr->error = 1;
	}
      else
	file_ptr->error = 0;
      mask = ready_mask & file_ptr->mask;
    }

  /* If there was a match, then call the handler.  */
  if (mask != 0)
    {
      event_loop_ui_debug_printf (file_ptr->is_ui,
				  "invoking fd file handler `%s`",
				  file_ptr->name.c_str ());
      file_ptr->proc (file_ptr->error, file_ptr->client_data);
    }
}

/* Wait for new events on the monitored file descriptors.  Run the
   event handler if the first descriptor that is detected by the poll.
   If BLOCK and if there are no events, this function will block in
   the call to poll.  Return 1 if an event was handled.  Return -1 if
   there are no file descriptors to monitor.  Return 1 if an event was
   handled, otherwise returns 0.  */

static int
gdb_wait_for_event (int block)
{
  file_handler *file_ptr;
  int num_found = 0;

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

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

  if (block)
    update_wait_timeout ();

#ifdef HAVE_POLL
  if (use_poll)
    {
      int timeout;

      if (block)
	timeout = gdb_notifier.timeout_valid ? gdb_notifier.poll_timeout : -1;
      else
	timeout = 0;

      num_found = poll (gdb_notifier.poll_fds,
			(unsigned long) gdb_notifier.num_fds, timeout);

      /* Don't print anything if we get out of poll because of a
	 signal.  */
      if (num_found == -1 && errno != EINTR)
	perror_with_name (("poll"));
    }
  else
#endif /* HAVE_POLL */
    {
      struct timeval select_timeout;
      struct timeval *timeout_p;

      if (block)
	timeout_p = gdb_notifier.timeout_valid
	  ? &gdb_notifier.select_timeout : NULL;
      else
	{
	  memset (&select_timeout, 0, sizeof (select_timeout));
	  timeout_p = &select_timeout;
	}

      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 = gdb_select (gdb_notifier.num_fds,
			      &gdb_notifier.ready_masks[0],
			      &gdb_notifier.ready_masks[1],
			      &gdb_notifier.ready_masks[2],
			      timeout_p);

      /* 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]);

	  /* Dont print anything if we got a signal, let gdb handle
	     it.  */
	  if (errno != EINTR)
	    perror_with_name (("select"));
	}
    }

  /* Avoid looking at poll_fds[i]->revents if no event fired.  */
  if (num_found <= 0)
    return 0;

  /* Run event handlers.  We always run just one handler and go back
     to polling, in case a handler changes the notifier list.  Since
     events for sources we haven't consumed yet wake poll/select
     immediately, no event is lost.  */

  /* To level the fairness across event descriptors, we handle them in
     a round-robin-like fashion.  The number and order of descriptors
     may change between invocations, but this is good enough.  */
#ifdef HAVE_POLL
  if (use_poll)
    {
      int i;
      int mask;

      while (1)
	{
	  if (gdb_notifier.next_poll_fds_index >= gdb_notifier.num_fds)
	    gdb_notifier.next_poll_fds_index = 0;
	  i = gdb_notifier.next_poll_fds_index++;

	  gdb_assert (i < gdb_notifier.num_fds);
	  if ((gdb_notifier.poll_fds + i)->revents)
	    break;
	}

      for (file_ptr = gdb_notifier.first_file_handler;
	   file_ptr != NULL;
	   file_ptr = file_ptr->next_file)
	{
	  if (file_ptr->fd == (gdb_notifier.poll_fds + i)->fd)
	    break;
	}
      gdb_assert (file_ptr != NULL);

      mask = (gdb_notifier.poll_fds + i)->revents;
      handle_file_event (file_ptr, mask);
      return 1;
    }
  else
#endif /* HAVE_POLL */
    {
      /* See comment about even source fairness above.  */
      int mask = 0;

      do
	{
	  file_ptr = get_next_file_handler_to_handle_and_advance ();

	  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;
	}
      while (mask == 0);

      handle_file_event (file_ptr, mask);
      return 1;
    }
  return 0;
}

/* Create a timer that will expire in MS milliseconds from now.  When
   the timer is ready, PROC will be executed.  At creation, the timer
   is added to the timers queue.  This queue is kept sorted in order
   of increasing timers.  Return a handle to the timer struct.  */

int
create_timer (int ms, timer_handler_func *proc,
	      gdb_client_data client_data)
{
  using namespace std::chrono;
  struct gdb_timer *timer_ptr, *timer_index, *prev_timer;

  steady_clock::time_point time_now = steady_clock::now ();

  timer_ptr = new gdb_timer ();
  timer_ptr->when = time_now + milliseconds (ms);
  timer_ptr->proc = proc;
  timer_ptr->client_data = client_data;
  timer_list.num_timers++;
  timer_ptr->timer_id = timer_list.num_timers;

  /* Now add the timer to the timer queue, making sure it is sorted in
     increasing order of expiration.  */

  for (timer_index = timer_list.first_timer;
       timer_index != NULL;
       timer_index = timer_index->next)
    {
      if (timer_index->when > timer_ptr->when)
	break;
    }

  if (timer_index == timer_list.first_timer)
    {
      timer_ptr->next = timer_list.first_timer;
      timer_list.first_timer = timer_ptr;

    }
  else
    {
      for (prev_timer = timer_list.first_timer;
	   prev_timer->next != timer_index;
	   prev_timer = prev_timer->next)
	;

      prev_timer->next = timer_ptr;
      timer_ptr->next = timer_index;
    }

  gdb_notifier.timeout_valid = 0;
  return timer_ptr->timer_id;
}

/* There is a chance that the creator of the timer wants to get rid of
   it before it expires.  */
void
delete_timer (int id)
{
  struct gdb_timer *timer_ptr, *prev_timer = NULL;

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

  for (timer_ptr = timer_list.first_timer; timer_ptr != NULL;
       timer_ptr = timer_ptr->next)
    {
      if (timer_ptr->timer_id == id)
	break;
    }

  if (timer_ptr == NULL)
    return;
  /* Get rid of the timer in the timer list.  */
  if (timer_ptr == timer_list.first_timer)
    timer_list.first_timer = timer_ptr->next;
  else
    {
      for (prev_timer = timer_list.first_timer;
	   prev_timer->next != timer_ptr;
	   prev_timer = prev_timer->next)
	;
      prev_timer->next = timer_ptr->next;
    }
  delete timer_ptr;

  gdb_notifier.timeout_valid = 0;
}

/* Convert a std::chrono duration to a struct timeval.  */

template<typename Duration>
static struct timeval
duration_cast_timeval (const Duration &d)
{
  using namespace std::chrono;
  seconds sec = duration_cast<seconds> (d);
  microseconds msec = duration_cast<microseconds> (d - sec);

  struct timeval tv;
  tv.tv_sec = sec.count ();
  tv.tv_usec = msec.count ();
  return tv;
}

/* Update the timeout for the select() or poll().  Returns true if the
   timer has already expired, false otherwise.  */

static int
update_wait_timeout (void)
{
  if (timer_list.first_timer != NULL)
    {
      using namespace std::chrono;
      steady_clock::time_point time_now = steady_clock::now ();
      struct timeval timeout;

      if (timer_list.first_timer->when < time_now)
	{
	  /* It expired already.  */
	  timeout.tv_sec = 0;
	  timeout.tv_usec = 0;
	}
      else
	{
	  steady_clock::duration d = timer_list.first_timer->when - time_now;
	  timeout = duration_cast_timeval (d);
	}

      /* Update the timeout for select/ poll.  */
#ifdef HAVE_POLL
      if (use_poll)
	gdb_notifier.poll_timeout = timeout.tv_sec * 1000;
      else
#endif /* HAVE_POLL */
	{
	  gdb_notifier.select_timeout.tv_sec = timeout.tv_sec;
	  gdb_notifier.select_timeout.tv_usec = timeout.tv_usec;
	}
      gdb_notifier.timeout_valid = 1;

      if (timer_list.first_timer->when < time_now)
	return 1;
    }
  else
    gdb_notifier.timeout_valid = 0;

  return 0;
}

/* Check whether a timer in the timers queue is ready.  If a timer is
   ready, call its handler and return.  Update the timeout for the
   select() or poll() as well.  Return 1 if an event was handled,
   otherwise returns 0.*/

static int
poll_timers (void)
{
  if (update_wait_timeout ())
    {
      struct gdb_timer *timer_ptr = timer_list.first_timer;
      timer_handler_func *proc = timer_ptr->proc;
      gdb_client_data client_data = timer_ptr->client_data;

      /* Get rid of the timer from the beginning of the list.  */
      timer_list.first_timer = timer_ptr->next;

      /* Delete the timer before calling the callback, not after, in
	 case the callback itself decides to try deleting the timer
	 too.  */
      delete timer_ptr;

      /* Call the procedure associated with that timer.  */
      (proc) (client_data);

      return 1;
    }

  return 0;
}
