xref: /dflybsd-src/contrib/gdb-7/gdb/event-loop.c (revision de8e141f24382815c10a4012d209bbbf7abf1112)
15796c8dcSSimon Schubert /* Event loop machinery for GDB, the GNU debugger.
2*ef5ccd6cSJohn Marino    Copyright (C) 1999-2013 Free Software Foundation, Inc.
35796c8dcSSimon Schubert    Written by Elena Zannoni <ezannoni@cygnus.com> of Cygnus Solutions.
45796c8dcSSimon Schubert 
55796c8dcSSimon Schubert    This file is part of GDB.
65796c8dcSSimon Schubert 
75796c8dcSSimon Schubert    This program is free software; you can redistribute it and/or modify
85796c8dcSSimon Schubert    it under the terms of the GNU General Public License as published by
95796c8dcSSimon Schubert    the Free Software Foundation; either version 3 of the License, or
105796c8dcSSimon Schubert    (at your option) any later version.
115796c8dcSSimon Schubert 
125796c8dcSSimon Schubert    This program is distributed in the hope that it will be useful,
135796c8dcSSimon Schubert    but WITHOUT ANY WARRANTY; without even the implied warranty of
145796c8dcSSimon Schubert    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
155796c8dcSSimon Schubert    GNU General Public License for more details.
165796c8dcSSimon Schubert 
175796c8dcSSimon Schubert    You should have received a copy of the GNU General Public License
185796c8dcSSimon Schubert    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
195796c8dcSSimon Schubert 
205796c8dcSSimon Schubert #include "defs.h"
215796c8dcSSimon Schubert #include "event-loop.h"
225796c8dcSSimon Schubert #include "event-top.h"
23*ef5ccd6cSJohn Marino #include "queue.h"
245796c8dcSSimon Schubert 
255796c8dcSSimon Schubert #ifdef HAVE_POLL
265796c8dcSSimon Schubert #if defined (HAVE_POLL_H)
275796c8dcSSimon Schubert #include <poll.h>
285796c8dcSSimon Schubert #elif defined (HAVE_SYS_POLL_H)
295796c8dcSSimon Schubert #include <sys/poll.h>
305796c8dcSSimon Schubert #endif
315796c8dcSSimon Schubert #endif
325796c8dcSSimon Schubert 
335796c8dcSSimon Schubert #include <sys/types.h>
345796c8dcSSimon Schubert #include "gdb_string.h"
355796c8dcSSimon Schubert #include <errno.h>
365796c8dcSSimon Schubert #include <sys/time.h>
375796c8dcSSimon Schubert #include "exceptions.h"
385796c8dcSSimon Schubert #include "gdb_assert.h"
395796c8dcSSimon Schubert #include "gdb_select.h"
405796c8dcSSimon Schubert 
41cf7f2e2dSJohn Marino /* Tell create_file_handler what events we are interested in.
42cf7f2e2dSJohn Marino    This is used by the select version of the event loop.  */
43cf7f2e2dSJohn Marino 
44cf7f2e2dSJohn Marino #define GDB_READABLE	(1<<1)
45cf7f2e2dSJohn Marino #define GDB_WRITABLE	(1<<2)
46cf7f2e2dSJohn Marino #define GDB_EXCEPTION	(1<<3)
47cf7f2e2dSJohn Marino 
485796c8dcSSimon Schubert /* Data point to pass to the event handler.  */
495796c8dcSSimon Schubert typedef union event_data
505796c8dcSSimon Schubert {
515796c8dcSSimon Schubert   void *ptr;
525796c8dcSSimon Schubert   int integer;
535796c8dcSSimon Schubert } event_data;
545796c8dcSSimon Schubert 
555796c8dcSSimon Schubert typedef struct gdb_event gdb_event;
565796c8dcSSimon Schubert typedef void (event_handler_func) (event_data);
575796c8dcSSimon Schubert 
585796c8dcSSimon Schubert /* Event for the GDB event system.  Events are queued by calling
595796c8dcSSimon Schubert    async_queue_event and serviced later on by gdb_do_one_event.  An
605796c8dcSSimon Schubert    event can be, for instance, a file descriptor becoming ready to be
615796c8dcSSimon Schubert    read.  Servicing an event simply means that the procedure PROC will
625796c8dcSSimon Schubert    be called.  We have 2 queues, one for file handlers that we listen
635796c8dcSSimon Schubert    to in the event loop, and one for the file handlers+events that are
645796c8dcSSimon Schubert    ready.  The procedure PROC associated with each event is dependant
655796c8dcSSimon Schubert    of the event source.  In the case of monitored file descriptors, it
665796c8dcSSimon Schubert    is always the same (handle_file_event).  Its duty is to invoke the
675796c8dcSSimon Schubert    handler associated with the file descriptor whose state change
685796c8dcSSimon Schubert    generated the event, plus doing other cleanups and such.  In the
695796c8dcSSimon Schubert    case of async signal handlers, it is
705796c8dcSSimon Schubert    invoke_async_signal_handler.  */
715796c8dcSSimon Schubert 
72*ef5ccd6cSJohn Marino typedef struct gdb_event
735796c8dcSSimon Schubert   {
745796c8dcSSimon Schubert     /* Procedure to call to service this event.  */
755796c8dcSSimon Schubert     event_handler_func *proc;
765796c8dcSSimon Schubert 
775796c8dcSSimon Schubert     /* Data to pass to the event handler.  */
785796c8dcSSimon Schubert     event_data data;
79*ef5ccd6cSJohn Marino   } *gdb_event_p;
805796c8dcSSimon Schubert 
815796c8dcSSimon Schubert /* Information about each file descriptor we register with the event
825796c8dcSSimon Schubert    loop.  */
835796c8dcSSimon Schubert 
845796c8dcSSimon Schubert typedef struct file_handler
855796c8dcSSimon Schubert   {
865796c8dcSSimon Schubert     int fd;			/* File descriptor.  */
875796c8dcSSimon Schubert     int mask;			/* Events we want to monitor: POLLIN, etc.  */
885796c8dcSSimon Schubert     int ready_mask;		/* Events that have been seen since
895796c8dcSSimon Schubert 				   the last time.  */
905796c8dcSSimon Schubert     handler_func *proc;		/* Procedure to call when fd is ready.  */
915796c8dcSSimon Schubert     gdb_client_data client_data;	/* Argument to pass to proc.  */
925796c8dcSSimon Schubert     int error;			/* Was an error detected on this fd?  */
935796c8dcSSimon Schubert     struct file_handler *next_file;	/* Next registered file descriptor.  */
945796c8dcSSimon Schubert   }
955796c8dcSSimon Schubert file_handler;
965796c8dcSSimon Schubert 
975796c8dcSSimon Schubert /* PROC is a function to be invoked when the READY flag is set.  This
985796c8dcSSimon Schubert    happens when there has been a signal and the corresponding signal
99c50c785cSJohn Marino    handler has 'triggered' this async_signal_handler for execution.
100c50c785cSJohn Marino    The actual work to be done in response to a signal will be carried
101c50c785cSJohn Marino    out by PROC at a later time, within process_event.  This provides a
102c50c785cSJohn Marino    deferred execution of signal handlers.
103c50c785cSJohn Marino 
1045796c8dcSSimon Schubert    Async_init_signals takes care of setting up such an
1055796c8dcSSimon Schubert    async_signal_handler for each interesting signal.  */
106c50c785cSJohn Marino 
1075796c8dcSSimon Schubert typedef struct async_signal_handler
1085796c8dcSSimon Schubert   {
109c50c785cSJohn Marino     int ready;			    /* If ready, call this handler
110c50c785cSJohn Marino 				       from the main event loop, using
111c50c785cSJohn Marino 				       invoke_async_handler.  */
112c50c785cSJohn Marino     struct async_signal_handler *next_handler;	/* Ptr to next handler.  */
113c50c785cSJohn Marino     sig_handler_func *proc;	    /* Function to call to do the work.  */
114c50c785cSJohn Marino     gdb_client_data client_data;    /* Argument to async_handler_func.  */
1155796c8dcSSimon Schubert   }
1165796c8dcSSimon Schubert async_signal_handler;
1175796c8dcSSimon Schubert 
1185796c8dcSSimon Schubert /* PROC is a function to be invoked when the READY flag is set.  This
1195796c8dcSSimon Schubert    happens when the event has been marked with
1205796c8dcSSimon Schubert    MARK_ASYNC_EVENT_HANDLER.  The actual work to be done in response
1215796c8dcSSimon Schubert    to an event will be carried out by PROC at a later time, within
1225796c8dcSSimon Schubert    process_event.  This provides a deferred execution of event
1235796c8dcSSimon Schubert    handlers.  */
1245796c8dcSSimon Schubert typedef struct async_event_handler
1255796c8dcSSimon Schubert   {
1265796c8dcSSimon Schubert     /* If ready, call this handler from the main event loop, using
1275796c8dcSSimon Schubert        invoke_event_handler.  */
1285796c8dcSSimon Schubert     int ready;
1295796c8dcSSimon Schubert 
1305796c8dcSSimon Schubert     /* Point to next handler.  */
1315796c8dcSSimon Schubert     struct async_event_handler *next_handler;
1325796c8dcSSimon Schubert 
1335796c8dcSSimon Schubert     /* Function to call to do the work.  */
1345796c8dcSSimon Schubert     async_event_handler_func *proc;
1355796c8dcSSimon Schubert 
1365796c8dcSSimon Schubert     /* Argument to PROC.  */
1375796c8dcSSimon Schubert     gdb_client_data client_data;
1385796c8dcSSimon Schubert   }
1395796c8dcSSimon Schubert async_event_handler;
1405796c8dcSSimon Schubert 
141*ef5ccd6cSJohn Marino DECLARE_QUEUE_P(gdb_event_p);
142*ef5ccd6cSJohn Marino DEFINE_QUEUE_P(gdb_event_p);
143*ef5ccd6cSJohn Marino static QUEUE(gdb_event_p) *event_queue = NULL;
1445796c8dcSSimon Schubert 
1455796c8dcSSimon Schubert /* Gdb_notifier is just a list of file descriptors gdb is interested in.
1465796c8dcSSimon Schubert    These are the input file descriptor, and the target file
1475796c8dcSSimon Schubert    descriptor.  We have two flavors of the notifier, one for platforms
1485796c8dcSSimon Schubert    that have the POLL function, the other for those that don't, and
1495796c8dcSSimon Schubert    only support SELECT.  Each of the elements in the gdb_notifier list is
1505796c8dcSSimon Schubert    basically a description of what kind of events gdb is interested
1515796c8dcSSimon Schubert    in, for each fd.  */
1525796c8dcSSimon Schubert 
1535796c8dcSSimon Schubert /* As of 1999-04-30 only the input file descriptor is registered with the
1545796c8dcSSimon Schubert    event loop.  */
1555796c8dcSSimon Schubert 
1565796c8dcSSimon Schubert /* Do we use poll or select ? */
1575796c8dcSSimon Schubert #ifdef HAVE_POLL
1585796c8dcSSimon Schubert #define USE_POLL 1
1595796c8dcSSimon Schubert #else
1605796c8dcSSimon Schubert #define USE_POLL 0
1615796c8dcSSimon Schubert #endif /* HAVE_POLL */
1625796c8dcSSimon Schubert 
1635796c8dcSSimon Schubert static unsigned char use_poll = USE_POLL;
1645796c8dcSSimon Schubert 
1655796c8dcSSimon Schubert #ifdef USE_WIN32API
1665796c8dcSSimon Schubert #include <windows.h>
1675796c8dcSSimon Schubert #include <io.h>
1685796c8dcSSimon Schubert #endif
1695796c8dcSSimon Schubert 
1705796c8dcSSimon Schubert static struct
1715796c8dcSSimon Schubert   {
1725796c8dcSSimon Schubert     /* Ptr to head of file handler list.  */
1735796c8dcSSimon Schubert     file_handler *first_file_handler;
1745796c8dcSSimon Schubert 
1755796c8dcSSimon Schubert #ifdef HAVE_POLL
1765796c8dcSSimon Schubert     /* Ptr to array of pollfd structures.  */
1775796c8dcSSimon Schubert     struct pollfd *poll_fds;
1785796c8dcSSimon Schubert 
1795796c8dcSSimon Schubert     /* Timeout in milliseconds for calls to poll().  */
1805796c8dcSSimon Schubert     int poll_timeout;
1815796c8dcSSimon Schubert #endif
1825796c8dcSSimon Schubert 
1835796c8dcSSimon Schubert     /* Masks to be used in the next call to select.
1845796c8dcSSimon Schubert        Bits are set in response to calls to create_file_handler.  */
1855796c8dcSSimon Schubert     fd_set check_masks[3];
1865796c8dcSSimon Schubert 
1875796c8dcSSimon Schubert     /* What file descriptors were found ready by select.  */
1885796c8dcSSimon Schubert     fd_set ready_masks[3];
1895796c8dcSSimon Schubert 
190c50c785cSJohn Marino     /* Number of file descriptors to monitor (for poll).  */
191c50c785cSJohn Marino     /* Number of valid bits (highest fd value + 1) (for select).  */
1925796c8dcSSimon Schubert     int num_fds;
1935796c8dcSSimon Schubert 
1945796c8dcSSimon Schubert     /* Time structure for calls to select().  */
1955796c8dcSSimon Schubert     struct timeval select_timeout;
1965796c8dcSSimon Schubert 
1975796c8dcSSimon Schubert     /* Flag to tell whether the timeout should be used.  */
1985796c8dcSSimon Schubert     int timeout_valid;
1995796c8dcSSimon Schubert   }
2005796c8dcSSimon Schubert gdb_notifier;
2015796c8dcSSimon Schubert 
2025796c8dcSSimon Schubert /* Structure associated with a timer.  PROC will be executed at the
2035796c8dcSSimon Schubert    first occasion after WHEN.  */
2045796c8dcSSimon Schubert struct gdb_timer
2055796c8dcSSimon Schubert   {
2065796c8dcSSimon Schubert     struct timeval when;
2075796c8dcSSimon Schubert     int timer_id;
2085796c8dcSSimon Schubert     struct gdb_timer *next;
209c50c785cSJohn Marino     timer_handler_func *proc;	    /* Function to call to do the work.  */
210c50c785cSJohn Marino     gdb_client_data client_data;    /* Argument to async_handler_func.  */
211cf7f2e2dSJohn Marino   };
2125796c8dcSSimon Schubert 
2135796c8dcSSimon Schubert /* List of currently active timers.  It is sorted in order of
2145796c8dcSSimon Schubert    increasing timers.  */
2155796c8dcSSimon Schubert static struct
2165796c8dcSSimon Schubert   {
2175796c8dcSSimon Schubert     /* Pointer to first in timer list.  */
2185796c8dcSSimon Schubert     struct gdb_timer *first_timer;
2195796c8dcSSimon Schubert 
2205796c8dcSSimon Schubert     /* Id of the last timer created.  */
2215796c8dcSSimon Schubert     int num_timers;
2225796c8dcSSimon Schubert   }
2235796c8dcSSimon Schubert timer_list;
2245796c8dcSSimon Schubert 
2255796c8dcSSimon Schubert /* All the async_signal_handlers gdb is interested in are kept onto
2265796c8dcSSimon Schubert    this list.  */
2275796c8dcSSimon Schubert static struct
2285796c8dcSSimon Schubert   {
2295796c8dcSSimon Schubert     /* Pointer to first in handler list.  */
2305796c8dcSSimon Schubert     async_signal_handler *first_handler;
2315796c8dcSSimon Schubert 
2325796c8dcSSimon Schubert     /* Pointer to last in handler list.  */
2335796c8dcSSimon Schubert     async_signal_handler *last_handler;
2345796c8dcSSimon Schubert   }
2355796c8dcSSimon Schubert sighandler_list;
2365796c8dcSSimon Schubert 
2375796c8dcSSimon Schubert /* All the async_event_handlers gdb is interested in are kept onto
2385796c8dcSSimon Schubert    this list.  */
2395796c8dcSSimon Schubert static struct
2405796c8dcSSimon Schubert   {
2415796c8dcSSimon Schubert     /* Pointer to first in handler list.  */
2425796c8dcSSimon Schubert     async_event_handler *first_handler;
2435796c8dcSSimon Schubert 
2445796c8dcSSimon Schubert     /* Pointer to last in handler list.  */
2455796c8dcSSimon Schubert     async_event_handler *last_handler;
2465796c8dcSSimon Schubert   }
2475796c8dcSSimon Schubert async_event_handler_list;
2485796c8dcSSimon Schubert 
2495796c8dcSSimon Schubert static int invoke_async_signal_handlers (void);
2505796c8dcSSimon Schubert static void create_file_handler (int fd, int mask, handler_func *proc,
2515796c8dcSSimon Schubert 				 gdb_client_data client_data);
2525796c8dcSSimon Schubert static void handle_file_event (event_data data);
2535796c8dcSSimon Schubert static void check_async_event_handlers (void);
2545796c8dcSSimon Schubert static int gdb_wait_for_event (int);
2555796c8dcSSimon Schubert static void poll_timers (void);
2565796c8dcSSimon Schubert 
2575796c8dcSSimon Schubert 
2585796c8dcSSimon Schubert /* Create a generic event, to be enqueued in the event queue for
2595796c8dcSSimon Schubert    processing.  PROC is the procedure associated to the event.  DATA
2605796c8dcSSimon Schubert    is passed to PROC upon PROC invocation.  */
2615796c8dcSSimon Schubert 
2625796c8dcSSimon Schubert static gdb_event *
create_event(event_handler_func proc,event_data data)2635796c8dcSSimon Schubert create_event (event_handler_func proc, event_data data)
2645796c8dcSSimon Schubert {
2655796c8dcSSimon Schubert   gdb_event *event;
2665796c8dcSSimon Schubert 
2675796c8dcSSimon Schubert   event = xmalloc (sizeof (*event));
2685796c8dcSSimon Schubert   event->proc = proc;
2695796c8dcSSimon Schubert   event->data = data;
2705796c8dcSSimon Schubert 
2715796c8dcSSimon Schubert   return event;
2725796c8dcSSimon Schubert }
2735796c8dcSSimon Schubert 
2745796c8dcSSimon Schubert /* Create a file event, to be enqueued in the event queue for
2755796c8dcSSimon Schubert    processing.  The procedure associated to this event is always
2765796c8dcSSimon Schubert    handle_file_event, which will in turn invoke the one that was
2775796c8dcSSimon Schubert    associated to FD when it was registered with the event loop.  */
2785796c8dcSSimon Schubert static gdb_event *
create_file_event(int fd)2795796c8dcSSimon Schubert create_file_event (int fd)
2805796c8dcSSimon Schubert {
2815796c8dcSSimon Schubert   event_data data;
2825796c8dcSSimon Schubert 
2835796c8dcSSimon Schubert   data.integer = fd;
2845796c8dcSSimon Schubert   return create_event (handle_file_event, data);
2855796c8dcSSimon Schubert }
2865796c8dcSSimon Schubert 
287*ef5ccd6cSJohn Marino 
288*ef5ccd6cSJohn Marino /* Free EVENT.  */
289*ef5ccd6cSJohn Marino 
290*ef5ccd6cSJohn Marino static void
gdb_event_xfree(struct gdb_event * event)291*ef5ccd6cSJohn Marino gdb_event_xfree (struct gdb_event *event)
292*ef5ccd6cSJohn Marino {
293*ef5ccd6cSJohn Marino   xfree (event);
294*ef5ccd6cSJohn Marino }
295*ef5ccd6cSJohn Marino 
296*ef5ccd6cSJohn Marino /* Initialize the event queue.  */
297*ef5ccd6cSJohn Marino 
298*ef5ccd6cSJohn Marino void
initialize_event_loop(void)299*ef5ccd6cSJohn Marino initialize_event_loop (void)
300*ef5ccd6cSJohn Marino {
301*ef5ccd6cSJohn Marino   event_queue = QUEUE_alloc (gdb_event_p, gdb_event_xfree);
302*ef5ccd6cSJohn Marino }
303*ef5ccd6cSJohn Marino 
3045796c8dcSSimon Schubert /* Process one event.
3055796c8dcSSimon Schubert    The event can be the next one to be serviced in the event queue,
3065796c8dcSSimon Schubert    or an asynchronous event handler can be invoked in response to
3075796c8dcSSimon Schubert    the reception of a signal.
3085796c8dcSSimon Schubert    If an event was processed (either way), 1 is returned otherwise
3095796c8dcSSimon Schubert    0 is returned.
3105796c8dcSSimon Schubert    Scan the queue from head to tail, processing therefore the high
3115796c8dcSSimon Schubert    priority events first, by invoking the associated event handler
3125796c8dcSSimon Schubert    procedure.  */
3135796c8dcSSimon Schubert static int
process_event(void)3145796c8dcSSimon Schubert process_event (void)
3155796c8dcSSimon Schubert {
3165796c8dcSSimon Schubert   /* First let's see if there are any asynchronous event handlers that
3175796c8dcSSimon Schubert      are ready.  These would be the result of invoking any of the
3185796c8dcSSimon Schubert      signal handlers.  */
3195796c8dcSSimon Schubert 
3205796c8dcSSimon Schubert   if (invoke_async_signal_handlers ())
3215796c8dcSSimon Schubert     return 1;
3225796c8dcSSimon Schubert 
3235796c8dcSSimon Schubert   /* Look in the event queue to find an event that is ready
3245796c8dcSSimon Schubert      to be processed.  */
3255796c8dcSSimon Schubert 
326*ef5ccd6cSJohn Marino   if (!QUEUE_is_empty (gdb_event_p, event_queue))
3275796c8dcSSimon Schubert     {
3285796c8dcSSimon Schubert       /* Let's get rid of the event from the event queue.  We need to
3295796c8dcSSimon Schubert 	 do this now because while processing the event, the proc
3305796c8dcSSimon Schubert 	 function could end up calling 'error' and therefore jump out
3315796c8dcSSimon Schubert 	 to the caller of this function, gdb_do_one_event.  In that
3325796c8dcSSimon Schubert 	 case, we would have on the event queue an event wich has been
3335796c8dcSSimon Schubert 	 processed, but not deleted.  */
334*ef5ccd6cSJohn Marino       gdb_event *event_ptr = QUEUE_deque (gdb_event_p, event_queue);
335*ef5ccd6cSJohn Marino       /* Call the handler for the event.  */
336*ef5ccd6cSJohn Marino       event_handler_func *proc = event_ptr->proc;
337*ef5ccd6cSJohn Marino       event_data data = event_ptr->data;
3385796c8dcSSimon Schubert 
339*ef5ccd6cSJohn Marino       gdb_event_xfree (event_ptr);
3405796c8dcSSimon Schubert 
3415796c8dcSSimon Schubert       /* Now call the procedure associated with the event.  */
3425796c8dcSSimon Schubert       (*proc) (data);
3435796c8dcSSimon Schubert       return 1;
3445796c8dcSSimon Schubert     }
3455796c8dcSSimon Schubert 
346c50c785cSJohn Marino   /* This is the case if there are no event on the event queue.  */
3475796c8dcSSimon Schubert   return 0;
3485796c8dcSSimon Schubert }
3495796c8dcSSimon Schubert 
3505796c8dcSSimon Schubert /* Process one high level event.  If nothing is ready at this time,
3515796c8dcSSimon Schubert    wait for something to happen (via gdb_wait_for_event), then process
3525796c8dcSSimon Schubert    it.  Returns >0 if something was done otherwise returns <0 (this
353a45ae5f8SJohn Marino    can happen if there are no event sources to wait for).  */
3545796c8dcSSimon Schubert 
3555796c8dcSSimon Schubert int
gdb_do_one_event(void)356a45ae5f8SJohn Marino gdb_do_one_event (void)
3575796c8dcSSimon Schubert {
3585796c8dcSSimon Schubert   static int event_source_head = 0;
3595796c8dcSSimon Schubert   const int number_of_sources = 3;
3605796c8dcSSimon Schubert   int current = 0;
3615796c8dcSSimon Schubert 
3625796c8dcSSimon Schubert   /* Any events already waiting in the queue?  */
3635796c8dcSSimon Schubert   if (process_event ())
3645796c8dcSSimon Schubert     return 1;
3655796c8dcSSimon Schubert 
3665796c8dcSSimon Schubert   /* To level the fairness across event sources, we poll them in a
3675796c8dcSSimon Schubert      round-robin fashion.  */
3685796c8dcSSimon Schubert   for (current = 0; current < number_of_sources; current++)
3695796c8dcSSimon Schubert     {
3705796c8dcSSimon Schubert       switch (event_source_head)
3715796c8dcSSimon Schubert 	{
3725796c8dcSSimon Schubert 	case 0:
3735796c8dcSSimon Schubert 	  /* Are any timers that are ready? If so, put an event on the
3745796c8dcSSimon Schubert 	     queue.  */
3755796c8dcSSimon Schubert 	  poll_timers ();
3765796c8dcSSimon Schubert 	  break;
3775796c8dcSSimon Schubert 	case 1:
3785796c8dcSSimon Schubert 	  /* Are there events already waiting to be collected on the
3795796c8dcSSimon Schubert 	     monitored file descriptors?  */
3805796c8dcSSimon Schubert 	  gdb_wait_for_event (0);
3815796c8dcSSimon Schubert 	  break;
3825796c8dcSSimon Schubert 	case 2:
3835796c8dcSSimon Schubert 	  /* Are there any asynchronous event handlers ready?  */
3845796c8dcSSimon Schubert 	  check_async_event_handlers ();
3855796c8dcSSimon Schubert 	  break;
3865796c8dcSSimon Schubert 	}
3875796c8dcSSimon Schubert 
3885796c8dcSSimon Schubert       event_source_head++;
3895796c8dcSSimon Schubert       if (event_source_head == number_of_sources)
3905796c8dcSSimon Schubert 	event_source_head = 0;
3915796c8dcSSimon Schubert     }
3925796c8dcSSimon Schubert 
3935796c8dcSSimon Schubert   /* Handle any new events collected.  */
3945796c8dcSSimon Schubert   if (process_event ())
3955796c8dcSSimon Schubert     return 1;
3965796c8dcSSimon Schubert 
3975796c8dcSSimon Schubert   /* Block waiting for a new event.  If gdb_wait_for_event returns -1,
3985796c8dcSSimon Schubert      we should get out because this means that there are no event
3995796c8dcSSimon Schubert      sources left.  This will make the event loop stop, and the
4005796c8dcSSimon Schubert      application exit.  */
4015796c8dcSSimon Schubert 
4025796c8dcSSimon Schubert   if (gdb_wait_for_event (1) < 0)
4035796c8dcSSimon Schubert     return -1;
4045796c8dcSSimon Schubert 
4055796c8dcSSimon Schubert   /* Handle any new events occurred while waiting.  */
4065796c8dcSSimon Schubert   if (process_event ())
4075796c8dcSSimon Schubert     return 1;
4085796c8dcSSimon Schubert 
4095796c8dcSSimon Schubert   /* If gdb_wait_for_event has returned 1, it means that one event has
4105796c8dcSSimon Schubert      been handled.  We break out of the loop.  */
4115796c8dcSSimon Schubert   return 1;
4125796c8dcSSimon Schubert }
4135796c8dcSSimon Schubert 
4145796c8dcSSimon Schubert /* Start up the event loop.  This is the entry point to the event loop
4155796c8dcSSimon Schubert    from the command loop.  */
4165796c8dcSSimon Schubert 
4175796c8dcSSimon Schubert void
start_event_loop(void)4185796c8dcSSimon Schubert start_event_loop (void)
4195796c8dcSSimon Schubert {
420a45ae5f8SJohn Marino   /* Loop until there is nothing to do.  This is the entry point to
421a45ae5f8SJohn Marino      the event loop engine.  gdb_do_one_event will process one event
422a45ae5f8SJohn Marino      for each invocation.  It blocks waiting for an event and then
423a45ae5f8SJohn Marino      processes it.  */
4245796c8dcSSimon Schubert   while (1)
4255796c8dcSSimon Schubert     {
426a45ae5f8SJohn Marino       volatile struct gdb_exception ex;
427a45ae5f8SJohn Marino       int result = 0;
4285796c8dcSSimon Schubert 
429a45ae5f8SJohn Marino       TRY_CATCH (ex, RETURN_MASK_ALL)
4305796c8dcSSimon Schubert 	{
431a45ae5f8SJohn Marino 	  result = gdb_do_one_event ();
432a45ae5f8SJohn Marino 	}
433a45ae5f8SJohn Marino       if (ex.reason < 0)
434a45ae5f8SJohn Marino 	{
435a45ae5f8SJohn Marino 	  exception_print (gdb_stderr, ex);
436a45ae5f8SJohn Marino 
4375796c8dcSSimon Schubert 	  /* If any exception escaped to here, we better enable
4385796c8dcSSimon Schubert 	     stdin.  Otherwise, any command that calls async_disable_stdin,
4395796c8dcSSimon Schubert 	     and then throws, will leave stdin inoperable.  */
4405796c8dcSSimon Schubert 	  async_enable_stdin ();
441a45ae5f8SJohn Marino 	  /* If we long-jumped out of do_one_event, we probably didn't
442a45ae5f8SJohn Marino 	     get around to resetting the prompt, which leaves readline
443a45ae5f8SJohn Marino 	     in a messed-up state.  Reset it here.  */
4445796c8dcSSimon Schubert 	  /* FIXME: this should really be a call to a hook that is
4455796c8dcSSimon Schubert 	     interface specific, because interfaces can display the
4465796c8dcSSimon Schubert 	     prompt in their own way.  */
4475796c8dcSSimon Schubert 	  display_gdb_prompt (0);
4485796c8dcSSimon Schubert 	  /* This call looks bizarre, but it is required.  If the user
4495796c8dcSSimon Schubert 	     entered a command that caused an error,
4505796c8dcSSimon Schubert 	     after_char_processing_hook won't be called from
4515796c8dcSSimon Schubert 	     rl_callback_read_char_wrapper.  Using a cleanup there
4525796c8dcSSimon Schubert 	     won't work, since we want this function to be called
4535796c8dcSSimon Schubert 	     after a new prompt is printed.  */
4545796c8dcSSimon Schubert 	  if (after_char_processing_hook)
4555796c8dcSSimon Schubert 	    (*after_char_processing_hook) ();
4565796c8dcSSimon Schubert 	  /* Maybe better to set a flag to be checked somewhere as to
4575796c8dcSSimon Schubert 	     whether display the prompt or not.  */
4585796c8dcSSimon Schubert 	}
459a45ae5f8SJohn Marino       if (result < 0)
460a45ae5f8SJohn Marino 	break;
4615796c8dcSSimon Schubert     }
4625796c8dcSSimon Schubert 
4635796c8dcSSimon Schubert   /* We are done with the event loop.  There are no more event sources
4645796c8dcSSimon Schubert      to listen to.  So we exit GDB.  */
4655796c8dcSSimon Schubert   return;
4665796c8dcSSimon Schubert }
4675796c8dcSSimon Schubert 
4685796c8dcSSimon Schubert 
4695796c8dcSSimon Schubert /* Wrapper function for create_file_handler, so that the caller
4705796c8dcSSimon Schubert    doesn't have to know implementation details about the use of poll
4715796c8dcSSimon Schubert    vs. select.  */
4725796c8dcSSimon Schubert void
add_file_handler(int fd,handler_func * proc,gdb_client_data client_data)4735796c8dcSSimon Schubert add_file_handler (int fd, handler_func * proc, gdb_client_data client_data)
4745796c8dcSSimon Schubert {
4755796c8dcSSimon Schubert #ifdef HAVE_POLL
4765796c8dcSSimon Schubert   struct pollfd fds;
4775796c8dcSSimon Schubert #endif
4785796c8dcSSimon Schubert 
4795796c8dcSSimon Schubert   if (use_poll)
4805796c8dcSSimon Schubert     {
4815796c8dcSSimon Schubert #ifdef HAVE_POLL
4825796c8dcSSimon Schubert       /* Check to see if poll () is usable.  If not, we'll switch to
4835796c8dcSSimon Schubert          use select.  This can happen on systems like
4845796c8dcSSimon Schubert          m68k-motorola-sys, `poll' cannot be used to wait for `stdin'.
4855796c8dcSSimon Schubert          On m68k-motorola-sysv, tty's are not stream-based and not
4865796c8dcSSimon Schubert          `poll'able.  */
4875796c8dcSSimon Schubert       fds.fd = fd;
4885796c8dcSSimon Schubert       fds.events = POLLIN;
4895796c8dcSSimon Schubert       if (poll (&fds, 1, 0) == 1 && (fds.revents & POLLNVAL))
4905796c8dcSSimon Schubert 	use_poll = 0;
4915796c8dcSSimon Schubert #else
4925796c8dcSSimon Schubert       internal_error (__FILE__, __LINE__,
4935796c8dcSSimon Schubert 		      _("use_poll without HAVE_POLL"));
4945796c8dcSSimon Schubert #endif /* HAVE_POLL */
4955796c8dcSSimon Schubert     }
4965796c8dcSSimon Schubert   if (use_poll)
4975796c8dcSSimon Schubert     {
4985796c8dcSSimon Schubert #ifdef HAVE_POLL
4995796c8dcSSimon Schubert       create_file_handler (fd, POLLIN, proc, client_data);
5005796c8dcSSimon Schubert #else
5015796c8dcSSimon Schubert       internal_error (__FILE__, __LINE__,
5025796c8dcSSimon Schubert 		      _("use_poll without HAVE_POLL"));
5035796c8dcSSimon Schubert #endif
5045796c8dcSSimon Schubert     }
5055796c8dcSSimon Schubert   else
506c50c785cSJohn Marino     create_file_handler (fd, GDB_READABLE | GDB_EXCEPTION,
507c50c785cSJohn Marino 			 proc, client_data);
5085796c8dcSSimon Schubert }
5095796c8dcSSimon Schubert 
5105796c8dcSSimon Schubert /* Add a file handler/descriptor to the list of descriptors we are
5115796c8dcSSimon Schubert    interested in.
512c50c785cSJohn Marino 
5135796c8dcSSimon Schubert    FD is the file descriptor for the file/stream to be listened to.
514c50c785cSJohn Marino 
515c50c785cSJohn Marino    For the poll case, MASK is a combination (OR) of POLLIN,
516c50c785cSJohn Marino    POLLRDNORM, POLLRDBAND, POLLPRI, POLLOUT, POLLWRNORM, POLLWRBAND:
517c50c785cSJohn Marino    these are the events we are interested in.  If any of them occurs,
518c50c785cSJohn Marino    proc should be called.
519c50c785cSJohn Marino 
520c50c785cSJohn Marino    For the select case, MASK is a combination of READABLE, WRITABLE,
521c50c785cSJohn Marino    EXCEPTION.  PROC is the procedure that will be called when an event
522c50c785cSJohn Marino    occurs for FD.  CLIENT_DATA is the argument to pass to PROC.  */
523c50c785cSJohn Marino 
5245796c8dcSSimon Schubert static void
create_file_handler(int fd,int mask,handler_func * proc,gdb_client_data client_data)525c50c785cSJohn Marino create_file_handler (int fd, int mask, handler_func * proc,
526c50c785cSJohn Marino 		     gdb_client_data client_data)
5275796c8dcSSimon Schubert {
5285796c8dcSSimon Schubert   file_handler *file_ptr;
5295796c8dcSSimon Schubert 
5305796c8dcSSimon Schubert   /* Do we already have a file handler for this file?  (We may be
5315796c8dcSSimon Schubert      changing its associated procedure).  */
5325796c8dcSSimon Schubert   for (file_ptr = gdb_notifier.first_file_handler; file_ptr != NULL;
5335796c8dcSSimon Schubert        file_ptr = file_ptr->next_file)
5345796c8dcSSimon Schubert     {
5355796c8dcSSimon Schubert       if (file_ptr->fd == fd)
5365796c8dcSSimon Schubert 	break;
5375796c8dcSSimon Schubert     }
5385796c8dcSSimon Schubert 
5395796c8dcSSimon Schubert   /* It is a new file descriptor.  Add it to the list.  Otherwise, just
5405796c8dcSSimon Schubert      change the data associated with it.  */
5415796c8dcSSimon Schubert   if (file_ptr == NULL)
5425796c8dcSSimon Schubert     {
5435796c8dcSSimon Schubert       file_ptr = (file_handler *) xmalloc (sizeof (file_handler));
5445796c8dcSSimon Schubert       file_ptr->fd = fd;
5455796c8dcSSimon Schubert       file_ptr->ready_mask = 0;
5465796c8dcSSimon Schubert       file_ptr->next_file = gdb_notifier.first_file_handler;
5475796c8dcSSimon Schubert       gdb_notifier.first_file_handler = file_ptr;
5485796c8dcSSimon Schubert 
5495796c8dcSSimon Schubert       if (use_poll)
5505796c8dcSSimon Schubert 	{
5515796c8dcSSimon Schubert #ifdef HAVE_POLL
5525796c8dcSSimon Schubert 	  gdb_notifier.num_fds++;
5535796c8dcSSimon Schubert 	  if (gdb_notifier.poll_fds)
5545796c8dcSSimon Schubert 	    gdb_notifier.poll_fds =
5555796c8dcSSimon Schubert 	      (struct pollfd *) xrealloc (gdb_notifier.poll_fds,
5565796c8dcSSimon Schubert 					  (gdb_notifier.num_fds
5575796c8dcSSimon Schubert 					   * sizeof (struct pollfd)));
5585796c8dcSSimon Schubert 	  else
5595796c8dcSSimon Schubert 	    gdb_notifier.poll_fds =
5605796c8dcSSimon Schubert 	      (struct pollfd *) xmalloc (sizeof (struct pollfd));
5615796c8dcSSimon Schubert 	  (gdb_notifier.poll_fds + gdb_notifier.num_fds - 1)->fd = fd;
5625796c8dcSSimon Schubert 	  (gdb_notifier.poll_fds + gdb_notifier.num_fds - 1)->events = mask;
5635796c8dcSSimon Schubert 	  (gdb_notifier.poll_fds + gdb_notifier.num_fds - 1)->revents = 0;
5645796c8dcSSimon Schubert #else
5655796c8dcSSimon Schubert 	  internal_error (__FILE__, __LINE__,
5665796c8dcSSimon Schubert 			  _("use_poll without HAVE_POLL"));
5675796c8dcSSimon Schubert #endif /* HAVE_POLL */
5685796c8dcSSimon Schubert 	}
5695796c8dcSSimon Schubert       else
5705796c8dcSSimon Schubert 	{
5715796c8dcSSimon Schubert 	  if (mask & GDB_READABLE)
5725796c8dcSSimon Schubert 	    FD_SET (fd, &gdb_notifier.check_masks[0]);
5735796c8dcSSimon Schubert 	  else
5745796c8dcSSimon Schubert 	    FD_CLR (fd, &gdb_notifier.check_masks[0]);
5755796c8dcSSimon Schubert 
5765796c8dcSSimon Schubert 	  if (mask & GDB_WRITABLE)
5775796c8dcSSimon Schubert 	    FD_SET (fd, &gdb_notifier.check_masks[1]);
5785796c8dcSSimon Schubert 	  else
5795796c8dcSSimon Schubert 	    FD_CLR (fd, &gdb_notifier.check_masks[1]);
5805796c8dcSSimon Schubert 
5815796c8dcSSimon Schubert 	  if (mask & GDB_EXCEPTION)
5825796c8dcSSimon Schubert 	    FD_SET (fd, &gdb_notifier.check_masks[2]);
5835796c8dcSSimon Schubert 	  else
5845796c8dcSSimon Schubert 	    FD_CLR (fd, &gdb_notifier.check_masks[2]);
5855796c8dcSSimon Schubert 
5865796c8dcSSimon Schubert 	  if (gdb_notifier.num_fds <= fd)
5875796c8dcSSimon Schubert 	    gdb_notifier.num_fds = fd + 1;
5885796c8dcSSimon Schubert 	}
5895796c8dcSSimon Schubert     }
5905796c8dcSSimon Schubert 
5915796c8dcSSimon Schubert   file_ptr->proc = proc;
5925796c8dcSSimon Schubert   file_ptr->client_data = client_data;
5935796c8dcSSimon Schubert   file_ptr->mask = mask;
5945796c8dcSSimon Schubert }
5955796c8dcSSimon Schubert 
5965796c8dcSSimon Schubert /* Remove the file descriptor FD from the list of monitored fd's:
5975796c8dcSSimon Schubert    i.e. we don't care anymore about events on the FD.  */
5985796c8dcSSimon Schubert void
delete_file_handler(int fd)5995796c8dcSSimon Schubert delete_file_handler (int fd)
6005796c8dcSSimon Schubert {
6015796c8dcSSimon Schubert   file_handler *file_ptr, *prev_ptr = NULL;
6025796c8dcSSimon Schubert   int i;
6035796c8dcSSimon Schubert #ifdef HAVE_POLL
6045796c8dcSSimon Schubert   int j;
6055796c8dcSSimon Schubert   struct pollfd *new_poll_fds;
6065796c8dcSSimon Schubert #endif
6075796c8dcSSimon Schubert 
6085796c8dcSSimon Schubert   /* Find the entry for the given file.  */
6095796c8dcSSimon Schubert 
6105796c8dcSSimon Schubert   for (file_ptr = gdb_notifier.first_file_handler; file_ptr != NULL;
6115796c8dcSSimon Schubert        file_ptr = file_ptr->next_file)
6125796c8dcSSimon Schubert     {
6135796c8dcSSimon Schubert       if (file_ptr->fd == fd)
6145796c8dcSSimon Schubert 	break;
6155796c8dcSSimon Schubert     }
6165796c8dcSSimon Schubert 
6175796c8dcSSimon Schubert   if (file_ptr == NULL)
6185796c8dcSSimon Schubert     return;
6195796c8dcSSimon Schubert 
6205796c8dcSSimon Schubert   if (use_poll)
6215796c8dcSSimon Schubert     {
6225796c8dcSSimon Schubert #ifdef HAVE_POLL
623c50c785cSJohn Marino       /* Create a new poll_fds array by copying every fd's information
624c50c785cSJohn Marino          but the one we want to get rid of.  */
6255796c8dcSSimon Schubert 
626c50c785cSJohn Marino       new_poll_fds = (struct pollfd *)
627c50c785cSJohn Marino 	xmalloc ((gdb_notifier.num_fds - 1) * sizeof (struct pollfd));
6285796c8dcSSimon Schubert 
6295796c8dcSSimon Schubert       for (i = 0, j = 0; i < gdb_notifier.num_fds; i++)
6305796c8dcSSimon Schubert 	{
6315796c8dcSSimon Schubert 	  if ((gdb_notifier.poll_fds + i)->fd != fd)
6325796c8dcSSimon Schubert 	    {
6335796c8dcSSimon Schubert 	      (new_poll_fds + j)->fd = (gdb_notifier.poll_fds + i)->fd;
6345796c8dcSSimon Schubert 	      (new_poll_fds + j)->events = (gdb_notifier.poll_fds + i)->events;
635c50c785cSJohn Marino 	      (new_poll_fds + j)->revents
636c50c785cSJohn Marino 		= (gdb_notifier.poll_fds + i)->revents;
6375796c8dcSSimon Schubert 	      j++;
6385796c8dcSSimon Schubert 	    }
6395796c8dcSSimon Schubert 	}
6405796c8dcSSimon Schubert       xfree (gdb_notifier.poll_fds);
6415796c8dcSSimon Schubert       gdb_notifier.poll_fds = new_poll_fds;
6425796c8dcSSimon Schubert       gdb_notifier.num_fds--;
6435796c8dcSSimon Schubert #else
6445796c8dcSSimon Schubert       internal_error (__FILE__, __LINE__,
6455796c8dcSSimon Schubert 		      _("use_poll without HAVE_POLL"));
6465796c8dcSSimon Schubert #endif /* HAVE_POLL */
6475796c8dcSSimon Schubert     }
6485796c8dcSSimon Schubert   else
6495796c8dcSSimon Schubert     {
6505796c8dcSSimon Schubert       if (file_ptr->mask & GDB_READABLE)
6515796c8dcSSimon Schubert 	FD_CLR (fd, &gdb_notifier.check_masks[0]);
6525796c8dcSSimon Schubert       if (file_ptr->mask & GDB_WRITABLE)
6535796c8dcSSimon Schubert 	FD_CLR (fd, &gdb_notifier.check_masks[1]);
6545796c8dcSSimon Schubert       if (file_ptr->mask & GDB_EXCEPTION)
6555796c8dcSSimon Schubert 	FD_CLR (fd, &gdb_notifier.check_masks[2]);
6565796c8dcSSimon Schubert 
6575796c8dcSSimon Schubert       /* Find current max fd.  */
6585796c8dcSSimon Schubert 
6595796c8dcSSimon Schubert       if ((fd + 1) == gdb_notifier.num_fds)
6605796c8dcSSimon Schubert 	{
6615796c8dcSSimon Schubert 	  gdb_notifier.num_fds--;
6625796c8dcSSimon Schubert 	  for (i = gdb_notifier.num_fds; i; i--)
6635796c8dcSSimon Schubert 	    {
6645796c8dcSSimon Schubert 	      if (FD_ISSET (i - 1, &gdb_notifier.check_masks[0])
6655796c8dcSSimon Schubert 		  || FD_ISSET (i - 1, &gdb_notifier.check_masks[1])
6665796c8dcSSimon Schubert 		  || FD_ISSET (i - 1, &gdb_notifier.check_masks[2]))
6675796c8dcSSimon Schubert 		break;
6685796c8dcSSimon Schubert 	    }
6695796c8dcSSimon Schubert 	  gdb_notifier.num_fds = i;
6705796c8dcSSimon Schubert 	}
6715796c8dcSSimon Schubert     }
6725796c8dcSSimon Schubert 
6735796c8dcSSimon Schubert   /* Deactivate the file descriptor, by clearing its mask,
6745796c8dcSSimon Schubert      so that it will not fire again.  */
6755796c8dcSSimon Schubert 
6765796c8dcSSimon Schubert   file_ptr->mask = 0;
6775796c8dcSSimon Schubert 
6785796c8dcSSimon Schubert   /* Get rid of the file handler in the file handler list.  */
6795796c8dcSSimon Schubert   if (file_ptr == gdb_notifier.first_file_handler)
6805796c8dcSSimon Schubert     gdb_notifier.first_file_handler = file_ptr->next_file;
6815796c8dcSSimon Schubert   else
6825796c8dcSSimon Schubert     {
6835796c8dcSSimon Schubert       for (prev_ptr = gdb_notifier.first_file_handler;
6845796c8dcSSimon Schubert 	   prev_ptr->next_file != file_ptr;
6855796c8dcSSimon Schubert 	   prev_ptr = prev_ptr->next_file)
6865796c8dcSSimon Schubert 	;
6875796c8dcSSimon Schubert       prev_ptr->next_file = file_ptr->next_file;
6885796c8dcSSimon Schubert     }
6895796c8dcSSimon Schubert   xfree (file_ptr);
6905796c8dcSSimon Schubert }
6915796c8dcSSimon Schubert 
6925796c8dcSSimon Schubert /* Handle the given event by calling the procedure associated to the
6935796c8dcSSimon Schubert    corresponding file handler.  Called by process_event indirectly,
6945796c8dcSSimon Schubert    through event_ptr->proc.  EVENT_FILE_DESC is file descriptor of the
6955796c8dcSSimon Schubert    event in the front of the event queue.  */
6965796c8dcSSimon Schubert static void
handle_file_event(event_data data)6975796c8dcSSimon Schubert handle_file_event (event_data data)
6985796c8dcSSimon Schubert {
6995796c8dcSSimon Schubert   file_handler *file_ptr;
7005796c8dcSSimon Schubert   int mask;
7015796c8dcSSimon Schubert #ifdef HAVE_POLL
7025796c8dcSSimon Schubert   int error_mask;
7035796c8dcSSimon Schubert #endif
7045796c8dcSSimon Schubert   int event_file_desc = data.integer;
7055796c8dcSSimon Schubert 
7065796c8dcSSimon Schubert   /* Search the file handler list to find one that matches the fd in
7075796c8dcSSimon Schubert      the event.  */
7085796c8dcSSimon Schubert   for (file_ptr = gdb_notifier.first_file_handler; file_ptr != NULL;
7095796c8dcSSimon Schubert        file_ptr = file_ptr->next_file)
7105796c8dcSSimon Schubert     {
7115796c8dcSSimon Schubert       if (file_ptr->fd == event_file_desc)
7125796c8dcSSimon Schubert 	{
7135796c8dcSSimon Schubert 	  /* With poll, the ready_mask could have any of three events
714c50c785cSJohn Marino 	     set to 1: POLLHUP, POLLERR, POLLNVAL.  These events
715c50c785cSJohn Marino 	     cannot be used in the requested event mask (events), but
716c50c785cSJohn Marino 	     they can be returned in the return mask (revents).  We
717c50c785cSJohn Marino 	     need to check for those event too, and add them to the
718c50c785cSJohn Marino 	     mask which will be passed to the handler.  */
7195796c8dcSSimon Schubert 
7205796c8dcSSimon Schubert 	  /* See if the desired events (mask) match the received
7215796c8dcSSimon Schubert 	     events (ready_mask).  */
7225796c8dcSSimon Schubert 
7235796c8dcSSimon Schubert 	  if (use_poll)
7245796c8dcSSimon Schubert 	    {
7255796c8dcSSimon Schubert #ifdef HAVE_POLL
726a45ae5f8SJohn Marino 	      /* POLLHUP means EOF, but can be combined with POLLIN to
727a45ae5f8SJohn Marino 		 signal more data to read.  */
7285796c8dcSSimon Schubert 	      error_mask = POLLHUP | POLLERR | POLLNVAL;
729a45ae5f8SJohn Marino 	      mask = file_ptr->ready_mask & (file_ptr->mask | error_mask);
7305796c8dcSSimon Schubert 
731a45ae5f8SJohn Marino 	      if ((mask & (POLLERR | POLLNVAL)) != 0)
7325796c8dcSSimon Schubert 		{
733c50c785cSJohn Marino 		  /* Work in progress.  We may need to tell somebody
734c50c785cSJohn Marino 		     what kind of error we had.  */
735a45ae5f8SJohn Marino 		  if (mask & POLLERR)
736c50c785cSJohn Marino 		    printf_unfiltered (_("Error detected on fd %d\n"),
737c50c785cSJohn Marino 				       file_ptr->fd);
738a45ae5f8SJohn Marino 		  if (mask & POLLNVAL)
739c50c785cSJohn Marino 		    printf_unfiltered (_("Invalid or non-`poll'able fd %d\n"),
740c50c785cSJohn Marino 				       file_ptr->fd);
7415796c8dcSSimon Schubert 		  file_ptr->error = 1;
7425796c8dcSSimon Schubert 		}
7435796c8dcSSimon Schubert 	      else
7445796c8dcSSimon Schubert 		file_ptr->error = 0;
7455796c8dcSSimon Schubert #else
7465796c8dcSSimon Schubert 	      internal_error (__FILE__, __LINE__,
7475796c8dcSSimon Schubert 			      _("use_poll without HAVE_POLL"));
7485796c8dcSSimon Schubert #endif /* HAVE_POLL */
7495796c8dcSSimon Schubert 	    }
7505796c8dcSSimon Schubert 	  else
7515796c8dcSSimon Schubert 	    {
7525796c8dcSSimon Schubert 	      if (file_ptr->ready_mask & GDB_EXCEPTION)
7535796c8dcSSimon Schubert 		{
754c50c785cSJohn Marino 		  printf_unfiltered (_("Exception condition detected "
755c50c785cSJohn Marino 				       "on fd %d\n"), file_ptr->fd);
7565796c8dcSSimon Schubert 		  file_ptr->error = 1;
7575796c8dcSSimon Schubert 		}
7585796c8dcSSimon Schubert 	      else
7595796c8dcSSimon Schubert 		file_ptr->error = 0;
7605796c8dcSSimon Schubert 	      mask = file_ptr->ready_mask & file_ptr->mask;
7615796c8dcSSimon Schubert 	    }
7625796c8dcSSimon Schubert 
7635796c8dcSSimon Schubert 	  /* Clear the received events for next time around.  */
7645796c8dcSSimon Schubert 	  file_ptr->ready_mask = 0;
7655796c8dcSSimon Schubert 
7665796c8dcSSimon Schubert 	  /* If there was a match, then call the handler.  */
7675796c8dcSSimon Schubert 	  if (mask != 0)
7685796c8dcSSimon Schubert 	    (*file_ptr->proc) (file_ptr->error, file_ptr->client_data);
7695796c8dcSSimon Schubert 	  break;
7705796c8dcSSimon Schubert 	}
7715796c8dcSSimon Schubert     }
7725796c8dcSSimon Schubert }
7735796c8dcSSimon Schubert 
7745796c8dcSSimon Schubert /* Called by gdb_do_one_event to wait for new events on the monitored
7755796c8dcSSimon Schubert    file descriptors.  Queue file events as they are detected by the
7765796c8dcSSimon Schubert    poll.  If BLOCK and if there are no events, this function will
777c50c785cSJohn Marino    block in the call to poll.  Return -1 if there are no file
7785796c8dcSSimon Schubert    descriptors to monitor, otherwise return 0.  */
7795796c8dcSSimon Schubert static int
gdb_wait_for_event(int block)7805796c8dcSSimon Schubert gdb_wait_for_event (int block)
7815796c8dcSSimon Schubert {
7825796c8dcSSimon Schubert   file_handler *file_ptr;
7835796c8dcSSimon Schubert   gdb_event *file_event_ptr;
7845796c8dcSSimon Schubert   int num_found = 0;
7855796c8dcSSimon Schubert   int i;
7865796c8dcSSimon Schubert 
7875796c8dcSSimon Schubert   /* Make sure all output is done before getting another event.  */
7885796c8dcSSimon Schubert   gdb_flush (gdb_stdout);
7895796c8dcSSimon Schubert   gdb_flush (gdb_stderr);
7905796c8dcSSimon Schubert 
7915796c8dcSSimon Schubert   if (gdb_notifier.num_fds == 0)
7925796c8dcSSimon Schubert     return -1;
7935796c8dcSSimon Schubert 
7945796c8dcSSimon Schubert   if (use_poll)
7955796c8dcSSimon Schubert     {
7965796c8dcSSimon Schubert #ifdef HAVE_POLL
7975796c8dcSSimon Schubert       int timeout;
7985796c8dcSSimon Schubert 
7995796c8dcSSimon Schubert       if (block)
8005796c8dcSSimon Schubert 	timeout = gdb_notifier.timeout_valid ? gdb_notifier.poll_timeout : -1;
8015796c8dcSSimon Schubert       else
8025796c8dcSSimon Schubert 	timeout = 0;
8035796c8dcSSimon Schubert 
8045796c8dcSSimon Schubert       num_found = poll (gdb_notifier.poll_fds,
8055796c8dcSSimon Schubert 			(unsigned long) gdb_notifier.num_fds, timeout);
8065796c8dcSSimon Schubert 
8075796c8dcSSimon Schubert       /* Don't print anything if we get out of poll because of a
8085796c8dcSSimon Schubert 	 signal.  */
8095796c8dcSSimon Schubert       if (num_found == -1 && errno != EINTR)
8105796c8dcSSimon Schubert 	perror_with_name (("poll"));
8115796c8dcSSimon Schubert #else
8125796c8dcSSimon Schubert       internal_error (__FILE__, __LINE__,
8135796c8dcSSimon Schubert 		      _("use_poll without HAVE_POLL"));
8145796c8dcSSimon Schubert #endif /* HAVE_POLL */
8155796c8dcSSimon Schubert     }
8165796c8dcSSimon Schubert   else
8175796c8dcSSimon Schubert     {
8185796c8dcSSimon Schubert       struct timeval select_timeout;
8195796c8dcSSimon Schubert       struct timeval *timeout_p;
820cf7f2e2dSJohn Marino 
8215796c8dcSSimon Schubert       if (block)
8225796c8dcSSimon Schubert 	timeout_p = gdb_notifier.timeout_valid
8235796c8dcSSimon Schubert 	  ? &gdb_notifier.select_timeout : NULL;
8245796c8dcSSimon Schubert       else
8255796c8dcSSimon Schubert 	{
8265796c8dcSSimon Schubert 	  memset (&select_timeout, 0, sizeof (select_timeout));
8275796c8dcSSimon Schubert 	  timeout_p = &select_timeout;
8285796c8dcSSimon Schubert 	}
8295796c8dcSSimon Schubert 
8305796c8dcSSimon Schubert       gdb_notifier.ready_masks[0] = gdb_notifier.check_masks[0];
8315796c8dcSSimon Schubert       gdb_notifier.ready_masks[1] = gdb_notifier.check_masks[1];
8325796c8dcSSimon Schubert       gdb_notifier.ready_masks[2] = gdb_notifier.check_masks[2];
8335796c8dcSSimon Schubert       num_found = gdb_select (gdb_notifier.num_fds,
8345796c8dcSSimon Schubert 			      &gdb_notifier.ready_masks[0],
8355796c8dcSSimon Schubert 			      &gdb_notifier.ready_masks[1],
8365796c8dcSSimon Schubert 			      &gdb_notifier.ready_masks[2],
8375796c8dcSSimon Schubert 			      timeout_p);
8385796c8dcSSimon Schubert 
8395796c8dcSSimon Schubert       /* Clear the masks after an error from select.  */
8405796c8dcSSimon Schubert       if (num_found == -1)
8415796c8dcSSimon Schubert 	{
8425796c8dcSSimon Schubert 	  FD_ZERO (&gdb_notifier.ready_masks[0]);
8435796c8dcSSimon Schubert 	  FD_ZERO (&gdb_notifier.ready_masks[1]);
8445796c8dcSSimon Schubert 	  FD_ZERO (&gdb_notifier.ready_masks[2]);
8455796c8dcSSimon Schubert 
8465796c8dcSSimon Schubert 	  /* Dont print anything if we got a signal, let gdb handle
8475796c8dcSSimon Schubert 	     it.  */
8485796c8dcSSimon Schubert 	  if (errno != EINTR)
8495796c8dcSSimon Schubert 	    perror_with_name (("select"));
8505796c8dcSSimon Schubert 	}
8515796c8dcSSimon Schubert     }
8525796c8dcSSimon Schubert 
8535796c8dcSSimon Schubert   /* Enqueue all detected file events.  */
8545796c8dcSSimon Schubert 
8555796c8dcSSimon Schubert   if (use_poll)
8565796c8dcSSimon Schubert     {
8575796c8dcSSimon Schubert #ifdef HAVE_POLL
8585796c8dcSSimon Schubert       for (i = 0; (i < gdb_notifier.num_fds) && (num_found > 0); i++)
8595796c8dcSSimon Schubert 	{
8605796c8dcSSimon Schubert 	  if ((gdb_notifier.poll_fds + i)->revents)
8615796c8dcSSimon Schubert 	    num_found--;
8625796c8dcSSimon Schubert 	  else
8635796c8dcSSimon Schubert 	    continue;
8645796c8dcSSimon Schubert 
8655796c8dcSSimon Schubert 	  for (file_ptr = gdb_notifier.first_file_handler;
8665796c8dcSSimon Schubert 	       file_ptr != NULL;
8675796c8dcSSimon Schubert 	       file_ptr = file_ptr->next_file)
8685796c8dcSSimon Schubert 	    {
8695796c8dcSSimon Schubert 	      if (file_ptr->fd == (gdb_notifier.poll_fds + i)->fd)
8705796c8dcSSimon Schubert 		break;
8715796c8dcSSimon Schubert 	    }
8725796c8dcSSimon Schubert 
8735796c8dcSSimon Schubert 	  if (file_ptr)
8745796c8dcSSimon Schubert 	    {
8755796c8dcSSimon Schubert 	      /* Enqueue an event only if this is still a new event for
8765796c8dcSSimon Schubert 	         this fd.  */
8775796c8dcSSimon Schubert 	      if (file_ptr->ready_mask == 0)
8785796c8dcSSimon Schubert 		{
8795796c8dcSSimon Schubert 		  file_event_ptr = create_file_event (file_ptr->fd);
880*ef5ccd6cSJohn Marino 		  QUEUE_enque (gdb_event_p, event_queue, file_event_ptr);
8815796c8dcSSimon Schubert 		}
8825796c8dcSSimon Schubert 	      file_ptr->ready_mask = (gdb_notifier.poll_fds + i)->revents;
8835796c8dcSSimon Schubert 	    }
8845796c8dcSSimon Schubert 	}
8855796c8dcSSimon Schubert #else
8865796c8dcSSimon Schubert       internal_error (__FILE__, __LINE__,
8875796c8dcSSimon Schubert 		      _("use_poll without HAVE_POLL"));
8885796c8dcSSimon Schubert #endif /* HAVE_POLL */
8895796c8dcSSimon Schubert     }
8905796c8dcSSimon Schubert   else
8915796c8dcSSimon Schubert     {
8925796c8dcSSimon Schubert       for (file_ptr = gdb_notifier.first_file_handler;
8935796c8dcSSimon Schubert 	   (file_ptr != NULL) && (num_found > 0);
8945796c8dcSSimon Schubert 	   file_ptr = file_ptr->next_file)
8955796c8dcSSimon Schubert 	{
8965796c8dcSSimon Schubert 	  int mask = 0;
8975796c8dcSSimon Schubert 
8985796c8dcSSimon Schubert 	  if (FD_ISSET (file_ptr->fd, &gdb_notifier.ready_masks[0]))
8995796c8dcSSimon Schubert 	    mask |= GDB_READABLE;
9005796c8dcSSimon Schubert 	  if (FD_ISSET (file_ptr->fd, &gdb_notifier.ready_masks[1]))
9015796c8dcSSimon Schubert 	    mask |= GDB_WRITABLE;
9025796c8dcSSimon Schubert 	  if (FD_ISSET (file_ptr->fd, &gdb_notifier.ready_masks[2]))
9035796c8dcSSimon Schubert 	    mask |= GDB_EXCEPTION;
9045796c8dcSSimon Schubert 
9055796c8dcSSimon Schubert 	  if (!mask)
9065796c8dcSSimon Schubert 	    continue;
9075796c8dcSSimon Schubert 	  else
9085796c8dcSSimon Schubert 	    num_found--;
9095796c8dcSSimon Schubert 
9105796c8dcSSimon Schubert 	  /* Enqueue an event only if this is still a new event for
9115796c8dcSSimon Schubert 	     this fd.  */
9125796c8dcSSimon Schubert 
9135796c8dcSSimon Schubert 	  if (file_ptr->ready_mask == 0)
9145796c8dcSSimon Schubert 	    {
9155796c8dcSSimon Schubert 	      file_event_ptr = create_file_event (file_ptr->fd);
916*ef5ccd6cSJohn Marino 	      QUEUE_enque (gdb_event_p, event_queue, file_event_ptr);
9175796c8dcSSimon Schubert 	    }
9185796c8dcSSimon Schubert 	  file_ptr->ready_mask = mask;
9195796c8dcSSimon Schubert 	}
9205796c8dcSSimon Schubert     }
9215796c8dcSSimon Schubert   return 0;
9225796c8dcSSimon Schubert }
9235796c8dcSSimon Schubert 
9245796c8dcSSimon Schubert 
9255796c8dcSSimon Schubert /* Create an asynchronous handler, allocating memory for it.
9265796c8dcSSimon Schubert    Return a pointer to the newly created handler.
9275796c8dcSSimon Schubert    This pointer will be used to invoke the handler by
9285796c8dcSSimon Schubert    invoke_async_signal_handler.
9295796c8dcSSimon Schubert    PROC is the function to call with CLIENT_DATA argument
9305796c8dcSSimon Schubert    whenever the handler is invoked.  */
9315796c8dcSSimon Schubert async_signal_handler *
create_async_signal_handler(sig_handler_func * proc,gdb_client_data client_data)932c50c785cSJohn Marino create_async_signal_handler (sig_handler_func * proc,
933c50c785cSJohn Marino 			     gdb_client_data client_data)
9345796c8dcSSimon Schubert {
9355796c8dcSSimon Schubert   async_signal_handler *async_handler_ptr;
9365796c8dcSSimon Schubert 
9375796c8dcSSimon Schubert   async_handler_ptr =
9385796c8dcSSimon Schubert     (async_signal_handler *) xmalloc (sizeof (async_signal_handler));
9395796c8dcSSimon Schubert   async_handler_ptr->ready = 0;
9405796c8dcSSimon Schubert   async_handler_ptr->next_handler = NULL;
9415796c8dcSSimon Schubert   async_handler_ptr->proc = proc;
9425796c8dcSSimon Schubert   async_handler_ptr->client_data = client_data;
9435796c8dcSSimon Schubert   if (sighandler_list.first_handler == NULL)
9445796c8dcSSimon Schubert     sighandler_list.first_handler = async_handler_ptr;
9455796c8dcSSimon Schubert   else
9465796c8dcSSimon Schubert     sighandler_list.last_handler->next_handler = async_handler_ptr;
9475796c8dcSSimon Schubert   sighandler_list.last_handler = async_handler_ptr;
9485796c8dcSSimon Schubert   return async_handler_ptr;
9495796c8dcSSimon Schubert }
9505796c8dcSSimon Schubert 
9515796c8dcSSimon Schubert /* Call the handler from HANDLER immediately.  This function runs
9525796c8dcSSimon Schubert    signal handlers when returning to the event loop would be too
9535796c8dcSSimon Schubert    slow.  */
9545796c8dcSSimon Schubert void
call_async_signal_handler(struct async_signal_handler * handler)9555796c8dcSSimon Schubert call_async_signal_handler (struct async_signal_handler *handler)
9565796c8dcSSimon Schubert {
9575796c8dcSSimon Schubert   (*handler->proc) (handler->client_data);
9585796c8dcSSimon Schubert }
9595796c8dcSSimon Schubert 
960c50c785cSJohn Marino /* Mark the handler (ASYNC_HANDLER_PTR) as ready.  This information
961c50c785cSJohn Marino    will be used when the handlers are invoked, after we have waited
962c50c785cSJohn Marino    for some event.  The caller of this function is the interrupt
963c50c785cSJohn Marino    handler associated with a signal.  */
9645796c8dcSSimon Schubert void
mark_async_signal_handler(async_signal_handler * async_handler_ptr)9655796c8dcSSimon Schubert mark_async_signal_handler (async_signal_handler * async_handler_ptr)
9665796c8dcSSimon Schubert {
9675796c8dcSSimon Schubert   async_handler_ptr->ready = 1;
9685796c8dcSSimon Schubert }
9695796c8dcSSimon Schubert 
9705796c8dcSSimon Schubert /* Call all the handlers that are ready.  Returns true if any was
9715796c8dcSSimon Schubert    indeed ready.  */
9725796c8dcSSimon Schubert static int
invoke_async_signal_handlers(void)9735796c8dcSSimon Schubert invoke_async_signal_handlers (void)
9745796c8dcSSimon Schubert {
9755796c8dcSSimon Schubert   async_signal_handler *async_handler_ptr;
9765796c8dcSSimon Schubert   int any_ready = 0;
9775796c8dcSSimon Schubert 
9785796c8dcSSimon Schubert   /* Invoke ready handlers.  */
9795796c8dcSSimon Schubert 
9805796c8dcSSimon Schubert   while (1)
9815796c8dcSSimon Schubert     {
9825796c8dcSSimon Schubert       for (async_handler_ptr = sighandler_list.first_handler;
9835796c8dcSSimon Schubert 	   async_handler_ptr != NULL;
9845796c8dcSSimon Schubert 	   async_handler_ptr = async_handler_ptr->next_handler)
9855796c8dcSSimon Schubert 	{
9865796c8dcSSimon Schubert 	  if (async_handler_ptr->ready)
9875796c8dcSSimon Schubert 	    break;
9885796c8dcSSimon Schubert 	}
9895796c8dcSSimon Schubert       if (async_handler_ptr == NULL)
9905796c8dcSSimon Schubert 	break;
9915796c8dcSSimon Schubert       any_ready = 1;
9925796c8dcSSimon Schubert       async_handler_ptr->ready = 0;
9935796c8dcSSimon Schubert       (*async_handler_ptr->proc) (async_handler_ptr->client_data);
9945796c8dcSSimon Schubert     }
9955796c8dcSSimon Schubert 
9965796c8dcSSimon Schubert   return any_ready;
9975796c8dcSSimon Schubert }
9985796c8dcSSimon Schubert 
9995796c8dcSSimon Schubert /* Delete an asynchronous handler (ASYNC_HANDLER_PTR).
10005796c8dcSSimon Schubert    Free the space allocated for it.  */
10015796c8dcSSimon Schubert void
delete_async_signal_handler(async_signal_handler ** async_handler_ptr)10025796c8dcSSimon Schubert delete_async_signal_handler (async_signal_handler ** async_handler_ptr)
10035796c8dcSSimon Schubert {
10045796c8dcSSimon Schubert   async_signal_handler *prev_ptr;
10055796c8dcSSimon Schubert 
10065796c8dcSSimon Schubert   if (sighandler_list.first_handler == (*async_handler_ptr))
10075796c8dcSSimon Schubert     {
10085796c8dcSSimon Schubert       sighandler_list.first_handler = (*async_handler_ptr)->next_handler;
10095796c8dcSSimon Schubert       if (sighandler_list.first_handler == NULL)
10105796c8dcSSimon Schubert 	sighandler_list.last_handler = NULL;
10115796c8dcSSimon Schubert     }
10125796c8dcSSimon Schubert   else
10135796c8dcSSimon Schubert     {
10145796c8dcSSimon Schubert       prev_ptr = sighandler_list.first_handler;
10155796c8dcSSimon Schubert       while (prev_ptr && prev_ptr->next_handler != (*async_handler_ptr))
10165796c8dcSSimon Schubert 	prev_ptr = prev_ptr->next_handler;
1017c50c785cSJohn Marino       gdb_assert (prev_ptr);
10185796c8dcSSimon Schubert       prev_ptr->next_handler = (*async_handler_ptr)->next_handler;
10195796c8dcSSimon Schubert       if (sighandler_list.last_handler == (*async_handler_ptr))
10205796c8dcSSimon Schubert 	sighandler_list.last_handler = prev_ptr;
10215796c8dcSSimon Schubert     }
10225796c8dcSSimon Schubert   xfree ((*async_handler_ptr));
10235796c8dcSSimon Schubert   (*async_handler_ptr) = NULL;
10245796c8dcSSimon Schubert }
10255796c8dcSSimon Schubert 
10265796c8dcSSimon Schubert /* Create an asynchronous event handler, allocating memory for it.
10275796c8dcSSimon Schubert    Return a pointer to the newly created handler.  PROC is the
10285796c8dcSSimon Schubert    function to call with CLIENT_DATA argument whenever the handler is
10295796c8dcSSimon Schubert    invoked.  */
10305796c8dcSSimon Schubert async_event_handler *
create_async_event_handler(async_event_handler_func * proc,gdb_client_data client_data)10315796c8dcSSimon Schubert create_async_event_handler (async_event_handler_func *proc,
10325796c8dcSSimon Schubert 			    gdb_client_data client_data)
10335796c8dcSSimon Schubert {
10345796c8dcSSimon Schubert   async_event_handler *h;
10355796c8dcSSimon Schubert 
10365796c8dcSSimon Schubert   h = xmalloc (sizeof (*h));
10375796c8dcSSimon Schubert   h->ready = 0;
10385796c8dcSSimon Schubert   h->next_handler = NULL;
10395796c8dcSSimon Schubert   h->proc = proc;
10405796c8dcSSimon Schubert   h->client_data = client_data;
10415796c8dcSSimon Schubert   if (async_event_handler_list.first_handler == NULL)
10425796c8dcSSimon Schubert     async_event_handler_list.first_handler = h;
10435796c8dcSSimon Schubert   else
10445796c8dcSSimon Schubert     async_event_handler_list.last_handler->next_handler = h;
10455796c8dcSSimon Schubert   async_event_handler_list.last_handler = h;
10465796c8dcSSimon Schubert   return h;
10475796c8dcSSimon Schubert }
10485796c8dcSSimon Schubert 
10495796c8dcSSimon Schubert /* Mark the handler (ASYNC_HANDLER_PTR) as ready.  This information
10505796c8dcSSimon Schubert    will be used by gdb_do_one_event.  The caller will be whoever
10515796c8dcSSimon Schubert    created the event source, and wants to signal that the event is
10525796c8dcSSimon Schubert    ready to be handled.  */
10535796c8dcSSimon Schubert void
mark_async_event_handler(async_event_handler * async_handler_ptr)10545796c8dcSSimon Schubert mark_async_event_handler (async_event_handler *async_handler_ptr)
10555796c8dcSSimon Schubert {
10565796c8dcSSimon Schubert   async_handler_ptr->ready = 1;
10575796c8dcSSimon Schubert }
10585796c8dcSSimon Schubert 
10595796c8dcSSimon Schubert struct async_event_handler_data
10605796c8dcSSimon Schubert {
10615796c8dcSSimon Schubert   async_event_handler_func* proc;
10625796c8dcSSimon Schubert   gdb_client_data client_data;
10635796c8dcSSimon Schubert };
10645796c8dcSSimon Schubert 
10655796c8dcSSimon Schubert static void
invoke_async_event_handler(event_data data)10665796c8dcSSimon Schubert invoke_async_event_handler (event_data data)
10675796c8dcSSimon Schubert {
10685796c8dcSSimon Schubert   struct async_event_handler_data *hdata = data.ptr;
10695796c8dcSSimon Schubert   async_event_handler_func* proc = hdata->proc;
10705796c8dcSSimon Schubert   gdb_client_data client_data = hdata->client_data;
10715796c8dcSSimon Schubert 
10725796c8dcSSimon Schubert   xfree (hdata);
10735796c8dcSSimon Schubert   (*proc) (client_data);
10745796c8dcSSimon Schubert }
10755796c8dcSSimon Schubert 
10765796c8dcSSimon Schubert /* Check if any asynchronous event handlers are ready, and queue
10775796c8dcSSimon Schubert    events in the ready queue for any that are.  */
10785796c8dcSSimon Schubert static void
check_async_event_handlers(void)10795796c8dcSSimon Schubert check_async_event_handlers (void)
10805796c8dcSSimon Schubert {
10815796c8dcSSimon Schubert   async_event_handler *async_handler_ptr;
10825796c8dcSSimon Schubert   struct async_event_handler_data *hdata;
10835796c8dcSSimon Schubert   struct gdb_event *event_ptr;
10845796c8dcSSimon Schubert   event_data data;
10855796c8dcSSimon Schubert 
10865796c8dcSSimon Schubert   for (async_handler_ptr = async_event_handler_list.first_handler;
10875796c8dcSSimon Schubert        async_handler_ptr != NULL;
10885796c8dcSSimon Schubert        async_handler_ptr = async_handler_ptr->next_handler)
10895796c8dcSSimon Schubert     {
10905796c8dcSSimon Schubert       if (async_handler_ptr->ready)
10915796c8dcSSimon Schubert 	{
10925796c8dcSSimon Schubert 	  async_handler_ptr->ready = 0;
10935796c8dcSSimon Schubert 
10945796c8dcSSimon Schubert 	  hdata = xmalloc (sizeof (*hdata));
10955796c8dcSSimon Schubert 
10965796c8dcSSimon Schubert 	  hdata->proc = async_handler_ptr->proc;
10975796c8dcSSimon Schubert 	  hdata->client_data = async_handler_ptr->client_data;
10985796c8dcSSimon Schubert 
10995796c8dcSSimon Schubert 	  data.ptr = hdata;
11005796c8dcSSimon Schubert 
11015796c8dcSSimon Schubert 	  event_ptr = create_event (invoke_async_event_handler, data);
1102*ef5ccd6cSJohn Marino 	  QUEUE_enque (gdb_event_p, event_queue, event_ptr);
11035796c8dcSSimon Schubert 	}
11045796c8dcSSimon Schubert     }
11055796c8dcSSimon Schubert }
11065796c8dcSSimon Schubert 
11075796c8dcSSimon Schubert /* Delete an asynchronous handler (ASYNC_HANDLER_PTR).
11085796c8dcSSimon Schubert    Free the space allocated for it.  */
11095796c8dcSSimon Schubert void
delete_async_event_handler(async_event_handler ** async_handler_ptr)11105796c8dcSSimon Schubert delete_async_event_handler (async_event_handler **async_handler_ptr)
11115796c8dcSSimon Schubert {
11125796c8dcSSimon Schubert   async_event_handler *prev_ptr;
11135796c8dcSSimon Schubert 
11145796c8dcSSimon Schubert   if (async_event_handler_list.first_handler == *async_handler_ptr)
11155796c8dcSSimon Schubert     {
1116c50c785cSJohn Marino       async_event_handler_list.first_handler
1117c50c785cSJohn Marino 	= (*async_handler_ptr)->next_handler;
11185796c8dcSSimon Schubert       if (async_event_handler_list.first_handler == NULL)
11195796c8dcSSimon Schubert 	async_event_handler_list.last_handler = NULL;
11205796c8dcSSimon Schubert     }
11215796c8dcSSimon Schubert   else
11225796c8dcSSimon Schubert     {
11235796c8dcSSimon Schubert       prev_ptr = async_event_handler_list.first_handler;
11245796c8dcSSimon Schubert       while (prev_ptr && prev_ptr->next_handler != *async_handler_ptr)
11255796c8dcSSimon Schubert 	prev_ptr = prev_ptr->next_handler;
1126c50c785cSJohn Marino       gdb_assert (prev_ptr);
11275796c8dcSSimon Schubert       prev_ptr->next_handler = (*async_handler_ptr)->next_handler;
11285796c8dcSSimon Schubert       if (async_event_handler_list.last_handler == (*async_handler_ptr))
11295796c8dcSSimon Schubert 	async_event_handler_list.last_handler = prev_ptr;
11305796c8dcSSimon Schubert     }
11315796c8dcSSimon Schubert   xfree (*async_handler_ptr);
11325796c8dcSSimon Schubert   *async_handler_ptr = NULL;
11335796c8dcSSimon Schubert }
11345796c8dcSSimon Schubert 
11355796c8dcSSimon Schubert /* Create a timer that will expire in MILLISECONDS from now.  When the
11365796c8dcSSimon Schubert    timer is ready, PROC will be executed.  At creation, the timer is
11375796c8dcSSimon Schubert    aded to the timers queue.  This queue is kept sorted in order of
11385796c8dcSSimon Schubert    increasing timers.  Return a handle to the timer struct.  */
11395796c8dcSSimon Schubert int
create_timer(int milliseconds,timer_handler_func * proc,gdb_client_data client_data)1140c50c785cSJohn Marino create_timer (int milliseconds, timer_handler_func * proc,
1141c50c785cSJohn Marino 	      gdb_client_data client_data)
11425796c8dcSSimon Schubert {
11435796c8dcSSimon Schubert   struct gdb_timer *timer_ptr, *timer_index, *prev_timer;
11445796c8dcSSimon Schubert   struct timeval time_now, delta;
11455796c8dcSSimon Schubert 
1146c50c785cSJohn Marino   /* Compute seconds.  */
11475796c8dcSSimon Schubert   delta.tv_sec = milliseconds / 1000;
1148c50c785cSJohn Marino   /* Compute microseconds.  */
11495796c8dcSSimon Schubert   delta.tv_usec = (milliseconds % 1000) * 1000;
11505796c8dcSSimon Schubert 
11515796c8dcSSimon Schubert   gettimeofday (&time_now, NULL);
11525796c8dcSSimon Schubert 
1153cf7f2e2dSJohn Marino   timer_ptr = (struct gdb_timer *) xmalloc (sizeof (*timer_ptr));
11545796c8dcSSimon Schubert   timer_ptr->when.tv_sec = time_now.tv_sec + delta.tv_sec;
11555796c8dcSSimon Schubert   timer_ptr->when.tv_usec = time_now.tv_usec + delta.tv_usec;
1156c50c785cSJohn Marino   /* Carry?  */
11575796c8dcSSimon Schubert   if (timer_ptr->when.tv_usec >= 1000000)
11585796c8dcSSimon Schubert     {
11595796c8dcSSimon Schubert       timer_ptr->when.tv_sec += 1;
11605796c8dcSSimon Schubert       timer_ptr->when.tv_usec -= 1000000;
11615796c8dcSSimon Schubert     }
11625796c8dcSSimon Schubert   timer_ptr->proc = proc;
11635796c8dcSSimon Schubert   timer_ptr->client_data = client_data;
11645796c8dcSSimon Schubert   timer_list.num_timers++;
11655796c8dcSSimon Schubert   timer_ptr->timer_id = timer_list.num_timers;
11665796c8dcSSimon Schubert 
11675796c8dcSSimon Schubert   /* Now add the timer to the timer queue, making sure it is sorted in
11685796c8dcSSimon Schubert      increasing order of expiration.  */
11695796c8dcSSimon Schubert 
11705796c8dcSSimon Schubert   for (timer_index = timer_list.first_timer;
11715796c8dcSSimon Schubert        timer_index != NULL;
11725796c8dcSSimon Schubert        timer_index = timer_index->next)
11735796c8dcSSimon Schubert     {
11745796c8dcSSimon Schubert       /* If the seconds field is greater or if it is the same, but the
11755796c8dcSSimon Schubert          microsecond field is greater.  */
1176cf7f2e2dSJohn Marino       if ((timer_index->when.tv_sec > timer_ptr->when.tv_sec)
1177cf7f2e2dSJohn Marino 	  || ((timer_index->when.tv_sec == timer_ptr->when.tv_sec)
11785796c8dcSSimon Schubert 	      && (timer_index->when.tv_usec > timer_ptr->when.tv_usec)))
11795796c8dcSSimon Schubert 	break;
11805796c8dcSSimon Schubert     }
11815796c8dcSSimon Schubert 
11825796c8dcSSimon Schubert   if (timer_index == timer_list.first_timer)
11835796c8dcSSimon Schubert     {
11845796c8dcSSimon Schubert       timer_ptr->next = timer_list.first_timer;
11855796c8dcSSimon Schubert       timer_list.first_timer = timer_ptr;
11865796c8dcSSimon Schubert 
11875796c8dcSSimon Schubert     }
11885796c8dcSSimon Schubert   else
11895796c8dcSSimon Schubert     {
11905796c8dcSSimon Schubert       for (prev_timer = timer_list.first_timer;
11915796c8dcSSimon Schubert 	   prev_timer->next != timer_index;
11925796c8dcSSimon Schubert 	   prev_timer = prev_timer->next)
11935796c8dcSSimon Schubert 	;
11945796c8dcSSimon Schubert 
11955796c8dcSSimon Schubert       prev_timer->next = timer_ptr;
11965796c8dcSSimon Schubert       timer_ptr->next = timer_index;
11975796c8dcSSimon Schubert     }
11985796c8dcSSimon Schubert 
11995796c8dcSSimon Schubert   gdb_notifier.timeout_valid = 0;
12005796c8dcSSimon Schubert   return timer_ptr->timer_id;
12015796c8dcSSimon Schubert }
12025796c8dcSSimon Schubert 
12035796c8dcSSimon Schubert /* There is a chance that the creator of the timer wants to get rid of
12045796c8dcSSimon Schubert    it before it expires.  */
12055796c8dcSSimon Schubert void
delete_timer(int id)12065796c8dcSSimon Schubert delete_timer (int id)
12075796c8dcSSimon Schubert {
12085796c8dcSSimon Schubert   struct gdb_timer *timer_ptr, *prev_timer = NULL;
12095796c8dcSSimon Schubert 
12105796c8dcSSimon Schubert   /* Find the entry for the given timer.  */
12115796c8dcSSimon Schubert 
12125796c8dcSSimon Schubert   for (timer_ptr = timer_list.first_timer; timer_ptr != NULL;
12135796c8dcSSimon Schubert        timer_ptr = timer_ptr->next)
12145796c8dcSSimon Schubert     {
12155796c8dcSSimon Schubert       if (timer_ptr->timer_id == id)
12165796c8dcSSimon Schubert 	break;
12175796c8dcSSimon Schubert     }
12185796c8dcSSimon Schubert 
12195796c8dcSSimon Schubert   if (timer_ptr == NULL)
12205796c8dcSSimon Schubert     return;
12215796c8dcSSimon Schubert   /* Get rid of the timer in the timer list.  */
12225796c8dcSSimon Schubert   if (timer_ptr == timer_list.first_timer)
12235796c8dcSSimon Schubert     timer_list.first_timer = timer_ptr->next;
12245796c8dcSSimon Schubert   else
12255796c8dcSSimon Schubert     {
12265796c8dcSSimon Schubert       for (prev_timer = timer_list.first_timer;
12275796c8dcSSimon Schubert 	   prev_timer->next != timer_ptr;
12285796c8dcSSimon Schubert 	   prev_timer = prev_timer->next)
12295796c8dcSSimon Schubert 	;
12305796c8dcSSimon Schubert       prev_timer->next = timer_ptr->next;
12315796c8dcSSimon Schubert     }
12325796c8dcSSimon Schubert   xfree (timer_ptr);
12335796c8dcSSimon Schubert 
12345796c8dcSSimon Schubert   gdb_notifier.timeout_valid = 0;
12355796c8dcSSimon Schubert }
12365796c8dcSSimon Schubert 
12375796c8dcSSimon Schubert /* When a timer event is put on the event queue, it will be handled by
12385796c8dcSSimon Schubert    this function.  Just call the associated procedure and delete the
12395796c8dcSSimon Schubert    timer event from the event queue.  Repeat this for each timer that
12405796c8dcSSimon Schubert    has expired.  */
12415796c8dcSSimon Schubert static void
handle_timer_event(event_data dummy)12425796c8dcSSimon Schubert handle_timer_event (event_data dummy)
12435796c8dcSSimon Schubert {
12445796c8dcSSimon Schubert   struct timeval time_now;
12455796c8dcSSimon Schubert   struct gdb_timer *timer_ptr, *saved_timer;
12465796c8dcSSimon Schubert 
12475796c8dcSSimon Schubert   gettimeofday (&time_now, NULL);
12485796c8dcSSimon Schubert   timer_ptr = timer_list.first_timer;
12495796c8dcSSimon Schubert 
12505796c8dcSSimon Schubert   while (timer_ptr != NULL)
12515796c8dcSSimon Schubert     {
1252cf7f2e2dSJohn Marino       if ((timer_ptr->when.tv_sec > time_now.tv_sec)
1253cf7f2e2dSJohn Marino 	  || ((timer_ptr->when.tv_sec == time_now.tv_sec)
1254cf7f2e2dSJohn Marino 	      && (timer_ptr->when.tv_usec > time_now.tv_usec)))
12555796c8dcSSimon Schubert 	break;
12565796c8dcSSimon Schubert 
12575796c8dcSSimon Schubert       /* Get rid of the timer from the beginning of the list.  */
12585796c8dcSSimon Schubert       timer_list.first_timer = timer_ptr->next;
12595796c8dcSSimon Schubert       saved_timer = timer_ptr;
12605796c8dcSSimon Schubert       timer_ptr = timer_ptr->next;
12615796c8dcSSimon Schubert       /* Call the procedure associated with that timer.  */
12625796c8dcSSimon Schubert       (*saved_timer->proc) (saved_timer->client_data);
12635796c8dcSSimon Schubert       xfree (saved_timer);
12645796c8dcSSimon Schubert     }
12655796c8dcSSimon Schubert 
12665796c8dcSSimon Schubert   gdb_notifier.timeout_valid = 0;
12675796c8dcSSimon Schubert }
12685796c8dcSSimon Schubert 
12695796c8dcSSimon Schubert /* Check whether any timers in the timers queue are ready.  If at least
12705796c8dcSSimon Schubert    one timer is ready, stick an event onto the event queue.  Even in
12715796c8dcSSimon Schubert    case more than one timer is ready, one event is enough, because the
12725796c8dcSSimon Schubert    handle_timer_event() will go through the timers list and call the
1273c50c785cSJohn Marino    procedures associated with all that have expired.l Update the
12745796c8dcSSimon Schubert    timeout for the select() or poll() as well.  */
12755796c8dcSSimon Schubert static void
poll_timers(void)12765796c8dcSSimon Schubert poll_timers (void)
12775796c8dcSSimon Schubert {
12785796c8dcSSimon Schubert   struct timeval time_now, delta;
12795796c8dcSSimon Schubert   gdb_event *event_ptr;
12805796c8dcSSimon Schubert 
12815796c8dcSSimon Schubert   if (timer_list.first_timer != NULL)
12825796c8dcSSimon Schubert     {
12835796c8dcSSimon Schubert       gettimeofday (&time_now, NULL);
12845796c8dcSSimon Schubert       delta.tv_sec = timer_list.first_timer->when.tv_sec - time_now.tv_sec;
12855796c8dcSSimon Schubert       delta.tv_usec = timer_list.first_timer->when.tv_usec - time_now.tv_usec;
1286c50c785cSJohn Marino       /* Borrow?  */
12875796c8dcSSimon Schubert       if (delta.tv_usec < 0)
12885796c8dcSSimon Schubert 	{
12895796c8dcSSimon Schubert 	  delta.tv_sec -= 1;
12905796c8dcSSimon Schubert 	  delta.tv_usec += 1000000;
12915796c8dcSSimon Schubert 	}
12925796c8dcSSimon Schubert 
12935796c8dcSSimon Schubert       /* Oops it expired already.  Tell select / poll to return
12945796c8dcSSimon Schubert          immediately.  (Cannot simply test if delta.tv_sec is negative
12955796c8dcSSimon Schubert          because time_t might be unsigned.)  */
12965796c8dcSSimon Schubert       if (timer_list.first_timer->when.tv_sec < time_now.tv_sec
12975796c8dcSSimon Schubert 	  || (timer_list.first_timer->when.tv_sec == time_now.tv_sec
12985796c8dcSSimon Schubert 	      && timer_list.first_timer->when.tv_usec < time_now.tv_usec))
12995796c8dcSSimon Schubert 	{
13005796c8dcSSimon Schubert 	  delta.tv_sec = 0;
13015796c8dcSSimon Schubert 	  delta.tv_usec = 0;
13025796c8dcSSimon Schubert 	}
13035796c8dcSSimon Schubert 
13045796c8dcSSimon Schubert       if (delta.tv_sec == 0 && delta.tv_usec == 0)
13055796c8dcSSimon Schubert 	{
13065796c8dcSSimon Schubert 	  event_ptr = (gdb_event *) xmalloc (sizeof (gdb_event));
13075796c8dcSSimon Schubert 	  event_ptr->proc = handle_timer_event;
13085796c8dcSSimon Schubert 	  event_ptr->data.integer = timer_list.first_timer->timer_id;
1309*ef5ccd6cSJohn Marino 	  QUEUE_enque (gdb_event_p, event_queue, event_ptr);
13105796c8dcSSimon Schubert 	}
13115796c8dcSSimon Schubert 
1312c50c785cSJohn Marino       /* Now we need to update the timeout for select/ poll, because
1313c50c785cSJohn Marino          we don't want to sit there while this timer is expiring.  */
13145796c8dcSSimon Schubert       if (use_poll)
13155796c8dcSSimon Schubert 	{
13165796c8dcSSimon Schubert #ifdef HAVE_POLL
13175796c8dcSSimon Schubert 	  gdb_notifier.poll_timeout = delta.tv_sec * 1000;
13185796c8dcSSimon Schubert #else
13195796c8dcSSimon Schubert 	  internal_error (__FILE__, __LINE__,
13205796c8dcSSimon Schubert 			  _("use_poll without HAVE_POLL"));
13215796c8dcSSimon Schubert #endif /* HAVE_POLL */
13225796c8dcSSimon Schubert 	}
13235796c8dcSSimon Schubert       else
13245796c8dcSSimon Schubert 	{
13255796c8dcSSimon Schubert 	  gdb_notifier.select_timeout.tv_sec = delta.tv_sec;
13265796c8dcSSimon Schubert 	  gdb_notifier.select_timeout.tv_usec = delta.tv_usec;
13275796c8dcSSimon Schubert 	}
13285796c8dcSSimon Schubert       gdb_notifier.timeout_valid = 1;
13295796c8dcSSimon Schubert     }
13305796c8dcSSimon Schubert   else
13315796c8dcSSimon Schubert     gdb_notifier.timeout_valid = 0;
13325796c8dcSSimon Schubert }
1333