Home | History | Annotate | Line # | Download | only in gdb
      1      1.1  christos /* Async events for the GDB event loop.
      2  1.1.1.3  christos    Copyright (C) 1999-2024 Free Software Foundation, Inc.
      3      1.1  christos 
      4      1.1  christos    This file is part of GDB.
      5      1.1  christos 
      6      1.1  christos    This program is free software; you can redistribute it and/or modify
      7      1.1  christos    it under the terms of the GNU General Public License as published by
      8      1.1  christos    the Free Software Foundation; either version 3 of the License, or
      9      1.1  christos    (at your option) any later version.
     10      1.1  christos 
     11      1.1  christos    This program is distributed in the hope that it will be useful,
     12      1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     13      1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14      1.1  christos    GNU General Public License for more details.
     15      1.1  christos 
     16      1.1  christos    You should have received a copy of the GNU General Public License
     17      1.1  christos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     18      1.1  christos 
     19      1.1  christos #include "async-event.h"
     20      1.1  christos 
     21      1.1  christos #include "ser-event.h"
     22      1.1  christos #include "top.h"
     23  1.1.1.3  christos #include "ui.h"
     24      1.1  christos 
     25      1.1  christos /* PROC is a function to be invoked when the READY flag is set.  This
     26      1.1  christos    happens when there has been a signal and the corresponding signal
     27      1.1  christos    handler has 'triggered' this async_signal_handler for execution.
     28      1.1  christos    The actual work to be done in response to a signal will be carried
     29      1.1  christos    out by PROC at a later time, within process_event.  This provides a
     30      1.1  christos    deferred execution of signal handlers.
     31      1.1  christos 
     32      1.1  christos    Async_init_signals takes care of setting up such an
     33      1.1  christos    async_signal_handler for each interesting signal.  */
     34      1.1  christos 
     35      1.1  christos struct async_signal_handler
     36      1.1  christos {
     37      1.1  christos   /* If ready, call this handler  from the main event loop, using
     38      1.1  christos      invoke_async_handler.  */
     39      1.1  christos   int ready;
     40      1.1  christos 
     41      1.1  christos   /* Pointer to next handler.  */
     42      1.1  christos   struct async_signal_handler *next_handler;
     43      1.1  christos 
     44      1.1  christos   /* Function to call to do the work.  */
     45      1.1  christos   sig_handler_func *proc;
     46      1.1  christos 
     47      1.1  christos   /* Argument to PROC.  */
     48      1.1  christos   gdb_client_data client_data;
     49  1.1.1.2  christos 
     50  1.1.1.2  christos   /* User-friendly name of this handler.  */
     51  1.1.1.2  christos   const char *name;
     52      1.1  christos };
     53      1.1  christos 
     54      1.1  christos /* PROC is a function to be invoked when the READY flag is set.  This
     55      1.1  christos    happens when the event has been marked with
     56      1.1  christos    MARK_ASYNC_EVENT_HANDLER.  The actual work to be done in response
     57      1.1  christos    to an event will be carried out by PROC at a later time, within
     58      1.1  christos    process_event.  This provides a deferred execution of event
     59      1.1  christos    handlers.  */
     60      1.1  christos struct async_event_handler
     61      1.1  christos {
     62      1.1  christos   /* If ready, call this handler from the main event loop, using
     63      1.1  christos      invoke_event_handler.  */
     64      1.1  christos   int ready;
     65      1.1  christos 
     66      1.1  christos   /* Pointer to next handler.  */
     67      1.1  christos   struct async_event_handler *next_handler;
     68      1.1  christos 
     69      1.1  christos   /* Function to call to do the work.  */
     70      1.1  christos   async_event_handler_func *proc;
     71      1.1  christos 
     72      1.1  christos   /* Argument to PROC.  */
     73      1.1  christos   gdb_client_data client_data;
     74  1.1.1.2  christos 
     75  1.1.1.2  christos   /* User-friendly name of this handler.  */
     76  1.1.1.2  christos   const char *name;
     77      1.1  christos };
     78      1.1  christos 
     79      1.1  christos /* All the async_signal_handlers gdb is interested in are kept onto
     80      1.1  christos    this list.  */
     81      1.1  christos static struct
     82      1.1  christos {
     83      1.1  christos   /* Pointer to first in handler list.  */
     84      1.1  christos   async_signal_handler *first_handler;
     85      1.1  christos 
     86      1.1  christos   /* Pointer to last in handler list.  */
     87      1.1  christos   async_signal_handler *last_handler;
     88      1.1  christos }
     89      1.1  christos sighandler_list;
     90      1.1  christos 
     91      1.1  christos /* All the async_event_handlers gdb is interested in are kept onto
     92      1.1  christos    this list.  */
     93      1.1  christos static struct
     94      1.1  christos {
     95      1.1  christos   /* Pointer to first in handler list.  */
     96      1.1  christos   async_event_handler *first_handler;
     97      1.1  christos 
     98      1.1  christos   /* Pointer to last in handler list.  */
     99      1.1  christos   async_event_handler *last_handler;
    100      1.1  christos }
    101      1.1  christos async_event_handler_list;
    102      1.1  christos 
    103      1.1  christos 
    104      1.1  christos /* This event is signalled whenever an asynchronous handler needs to
    105      1.1  christos    defer an action to the event loop.  */
    106      1.1  christos static struct serial_event *async_signal_handlers_serial_event;
    107      1.1  christos 
    108      1.1  christos /* Callback registered with ASYNC_SIGNAL_HANDLERS_SERIAL_EVENT.  */
    109      1.1  christos 
    110      1.1  christos static void
    111      1.1  christos async_signals_handler (int error, gdb_client_data client_data)
    112      1.1  christos {
    113      1.1  christos   /* Do nothing.  Handlers are run by invoke_async_signal_handlers
    114      1.1  christos      from instead.  */
    115      1.1  christos }
    116      1.1  christos 
    117      1.1  christos void
    118      1.1  christos initialize_async_signal_handlers (void)
    119      1.1  christos {
    120      1.1  christos   async_signal_handlers_serial_event = make_serial_event ();
    121      1.1  christos 
    122      1.1  christos   add_file_handler (serial_event_fd (async_signal_handlers_serial_event),
    123  1.1.1.2  christos 		    async_signals_handler, NULL, "async-signals");
    124      1.1  christos }
    125      1.1  christos 
    126      1.1  christos 
    127      1.1  christos 
    129      1.1  christos /* Create an asynchronous handler, allocating memory for it.
    130      1.1  christos    Return a pointer to the newly created handler.
    131      1.1  christos    This pointer will be used to invoke the handler by
    132      1.1  christos    invoke_async_signal_handler.
    133      1.1  christos    PROC is the function to call with CLIENT_DATA argument
    134      1.1  christos    whenever the handler is invoked.  */
    135      1.1  christos async_signal_handler *
    136  1.1.1.2  christos create_async_signal_handler (sig_handler_func * proc,
    137  1.1.1.2  christos 			     gdb_client_data client_data,
    138      1.1  christos 			     const char *name)
    139      1.1  christos {
    140      1.1  christos   async_signal_handler *async_handler_ptr;
    141      1.1  christos 
    142      1.1  christos   async_handler_ptr = XNEW (async_signal_handler);
    143      1.1  christos   async_handler_ptr->ready = 0;
    144      1.1  christos   async_handler_ptr->next_handler = NULL;
    145      1.1  christos   async_handler_ptr->proc = proc;
    146  1.1.1.2  christos   async_handler_ptr->client_data = client_data;
    147      1.1  christos   async_handler_ptr->name = name;
    148      1.1  christos   if (sighandler_list.first_handler == NULL)
    149      1.1  christos     sighandler_list.first_handler = async_handler_ptr;
    150      1.1  christos   else
    151      1.1  christos     sighandler_list.last_handler->next_handler = async_handler_ptr;
    152      1.1  christos   sighandler_list.last_handler = async_handler_ptr;
    153      1.1  christos   return async_handler_ptr;
    154      1.1  christos }
    155      1.1  christos 
    156      1.1  christos /* Mark the handler (ASYNC_HANDLER_PTR) as ready.  This information
    157      1.1  christos    will be used when the handlers are invoked, after we have waited
    158      1.1  christos    for some event.  The caller of this function is the interrupt
    159      1.1  christos    handler associated with a signal.  */
    160  1.1.1.2  christos void
    161      1.1  christos mark_async_signal_handler (async_signal_handler *async_handler_ptr)
    162  1.1.1.2  christos {
    163  1.1.1.2  christos   if (debug_event_loop != debug_event_loop_kind::OFF)
    164  1.1.1.2  christos     {
    165  1.1.1.2  christos       /* This is called by signal handlers, so we print it "by hand" using
    166  1.1.1.2  christos 	 the async-signal-safe methods.  */
    167  1.1.1.2  christos       const char head[] = ("[event-loop] mark_async_signal_handler: marking"
    168  1.1.1.2  christos 			   "async signal handler `");
    169  1.1.1.2  christos       gdb_stdlog->write_async_safe (head, strlen (head));
    170  1.1.1.2  christos 
    171  1.1.1.2  christos       gdb_stdlog->write_async_safe (async_handler_ptr->name,
    172  1.1.1.2  christos 				    strlen (async_handler_ptr->name));
    173  1.1.1.2  christos 
    174  1.1.1.2  christos       const char tail[] = "`\n";
    175  1.1.1.2  christos       gdb_stdlog->write_async_safe (tail, strlen (tail));
    176  1.1.1.2  christos     }
    177      1.1  christos 
    178      1.1  christos   async_handler_ptr->ready = 1;
    179      1.1  christos   serial_event_set (async_signal_handlers_serial_event);
    180      1.1  christos }
    181      1.1  christos 
    182      1.1  christos /* See event-loop.h.  */
    183      1.1  christos 
    184      1.1  christos void
    185      1.1  christos clear_async_signal_handler (async_signal_handler *async_handler_ptr)
    186  1.1.1.2  christos {
    187  1.1.1.2  christos   event_loop_debug_printf ("clearing async signal handler `%s`",
    188      1.1  christos 			   async_handler_ptr->name);
    189      1.1  christos   async_handler_ptr->ready = 0;
    190      1.1  christos }
    191      1.1  christos 
    192      1.1  christos /* See event-loop.h.  */
    193      1.1  christos 
    194      1.1  christos int
    195      1.1  christos async_signal_handler_is_marked (async_signal_handler *async_handler_ptr)
    196      1.1  christos {
    197      1.1  christos   return async_handler_ptr->ready;
    198      1.1  christos }
    199      1.1  christos 
    200      1.1  christos /* Call all the handlers that are ready.  Returns true if any was
    201      1.1  christos    indeed ready.  */
    202      1.1  christos 
    203      1.1  christos int
    204      1.1  christos invoke_async_signal_handlers (void)
    205      1.1  christos {
    206      1.1  christos   async_signal_handler *async_handler_ptr;
    207      1.1  christos   int any_ready = 0;
    208      1.1  christos 
    209      1.1  christos   /* We're going to handle all pending signals, so no need to wake up
    210      1.1  christos      the event loop again the next time around.  Note this must be
    211      1.1  christos      cleared _before_ calling the callbacks, to avoid races.  */
    212      1.1  christos   serial_event_clear (async_signal_handlers_serial_event);
    213      1.1  christos 
    214      1.1  christos   /* Invoke all ready handlers.  */
    215      1.1  christos 
    216      1.1  christos   while (1)
    217      1.1  christos     {
    218      1.1  christos       for (async_handler_ptr = sighandler_list.first_handler;
    219      1.1  christos 	   async_handler_ptr != NULL;
    220      1.1  christos 	   async_handler_ptr = async_handler_ptr->next_handler)
    221      1.1  christos 	{
    222      1.1  christos 	  if (async_handler_ptr->ready)
    223      1.1  christos 	    break;
    224      1.1  christos 	}
    225      1.1  christos       if (async_handler_ptr == NULL)
    226      1.1  christos 	break;
    227      1.1  christos       any_ready = 1;
    228      1.1  christos       async_handler_ptr->ready = 0;
    229      1.1  christos       /* Async signal handlers have no connection to whichever was the
    230      1.1  christos 	 current UI, and thus always run on the main one.  */
    231  1.1.1.2  christos       current_ui = main_ui;
    232  1.1.1.2  christos       event_loop_debug_printf ("invoking async signal handler `%s`",
    233      1.1  christos 			       async_handler_ptr->name);
    234      1.1  christos       (*async_handler_ptr->proc) (async_handler_ptr->client_data);
    235      1.1  christos     }
    236      1.1  christos 
    237      1.1  christos   return any_ready;
    238      1.1  christos }
    239      1.1  christos 
    240      1.1  christos /* Delete an asynchronous handler (ASYNC_HANDLER_PTR).
    241      1.1  christos    Free the space allocated for it.  */
    242      1.1  christos void
    243      1.1  christos delete_async_signal_handler (async_signal_handler ** async_handler_ptr)
    244      1.1  christos {
    245      1.1  christos   async_signal_handler *prev_ptr;
    246      1.1  christos 
    247      1.1  christos   if (sighandler_list.first_handler == (*async_handler_ptr))
    248      1.1  christos     {
    249      1.1  christos       sighandler_list.first_handler = (*async_handler_ptr)->next_handler;
    250      1.1  christos       if (sighandler_list.first_handler == NULL)
    251      1.1  christos 	sighandler_list.last_handler = NULL;
    252      1.1  christos     }
    253      1.1  christos   else
    254      1.1  christos     {
    255      1.1  christos       prev_ptr = sighandler_list.first_handler;
    256      1.1  christos       while (prev_ptr && prev_ptr->next_handler != (*async_handler_ptr))
    257      1.1  christos 	prev_ptr = prev_ptr->next_handler;
    258      1.1  christos       gdb_assert (prev_ptr);
    259      1.1  christos       prev_ptr->next_handler = (*async_handler_ptr)->next_handler;
    260      1.1  christos       if (sighandler_list.last_handler == (*async_handler_ptr))
    261      1.1  christos 	sighandler_list.last_handler = prev_ptr;
    262      1.1  christos     }
    263      1.1  christos   xfree ((*async_handler_ptr));
    264      1.1  christos   (*async_handler_ptr) = NULL;
    265      1.1  christos }
    266  1.1.1.2  christos 
    267  1.1.1.2  christos /* See async-event.h.  */
    268      1.1  christos 
    269      1.1  christos async_event_handler *
    270  1.1.1.2  christos create_async_event_handler (async_event_handler_func *proc,
    271  1.1.1.2  christos 			    gdb_client_data client_data,
    272      1.1  christos 			    const char *name)
    273      1.1  christos {
    274      1.1  christos   async_event_handler *h;
    275      1.1  christos 
    276      1.1  christos   h = XNEW (struct async_event_handler);
    277      1.1  christos   h->ready = 0;
    278      1.1  christos   h->next_handler = NULL;
    279      1.1  christos   h->proc = proc;
    280  1.1.1.2  christos   h->client_data = client_data;
    281      1.1  christos   h->name = name;
    282      1.1  christos   if (async_event_handler_list.first_handler == NULL)
    283      1.1  christos     async_event_handler_list.first_handler = h;
    284      1.1  christos   else
    285      1.1  christos     async_event_handler_list.last_handler->next_handler = h;
    286      1.1  christos   async_event_handler_list.last_handler = h;
    287      1.1  christos   return h;
    288      1.1  christos }
    289      1.1  christos 
    290      1.1  christos /* Mark the handler (ASYNC_HANDLER_PTR) as ready.  This information
    291      1.1  christos    will be used by gdb_do_one_event.  The caller will be whoever
    292      1.1  christos    created the event source, and wants to signal that the event is
    293      1.1  christos    ready to be handled.  */
    294      1.1  christos void
    295      1.1  christos mark_async_event_handler (async_event_handler *async_handler_ptr)
    296  1.1.1.2  christos {
    297  1.1.1.2  christos   event_loop_debug_printf ("marking async event handler `%s` "
    298  1.1.1.2  christos 			   "(previous state was %d)",
    299  1.1.1.2  christos 			   async_handler_ptr->name,
    300      1.1  christos 			   async_handler_ptr->ready);
    301      1.1  christos   async_handler_ptr->ready = 1;
    302      1.1  christos }
    303      1.1  christos 
    304      1.1  christos /* See event-loop.h.  */
    305      1.1  christos 
    306      1.1  christos void
    307      1.1  christos clear_async_event_handler (async_event_handler *async_handler_ptr)
    308  1.1.1.2  christos {
    309  1.1.1.2  christos   event_loop_debug_printf ("clearing async event handler `%s`",
    310      1.1  christos 			   async_handler_ptr->name);
    311      1.1  christos   async_handler_ptr->ready = 0;
    312      1.1  christos }
    313  1.1.1.2  christos 
    314  1.1.1.2  christos /* See event-loop.h.  */
    315  1.1.1.2  christos 
    316  1.1.1.2  christos bool
    317  1.1.1.2  christos async_event_handler_marked (async_event_handler *handler)
    318  1.1.1.2  christos {
    319  1.1.1.2  christos   return handler->ready;
    320  1.1.1.2  christos }
    321      1.1  christos 
    322      1.1  christos /* Check if asynchronous event handlers are ready, and call the
    323      1.1  christos    handler function for one that is.  */
    324      1.1  christos 
    325      1.1  christos int
    326      1.1  christos check_async_event_handlers ()
    327      1.1  christos {
    328      1.1  christos   async_event_handler *async_handler_ptr;
    329      1.1  christos 
    330      1.1  christos   for (async_handler_ptr = async_event_handler_list.first_handler;
    331      1.1  christos        async_handler_ptr != NULL;
    332      1.1  christos        async_handler_ptr = async_handler_ptr->next_handler)
    333      1.1  christos     {
    334      1.1  christos       if (async_handler_ptr->ready)
    335  1.1.1.2  christos 	{
    336  1.1.1.2  christos 	  event_loop_debug_printf ("invoking async event handler `%s`",
    337      1.1  christos 				   async_handler_ptr->name);
    338      1.1  christos 	  (*async_handler_ptr->proc) (async_handler_ptr->client_data);
    339      1.1  christos 	  return 1;
    340      1.1  christos 	}
    341      1.1  christos     }
    342      1.1  christos 
    343      1.1  christos   return 0;
    344      1.1  christos }
    345      1.1  christos 
    346      1.1  christos /* Delete an asynchronous handler (ASYNC_HANDLER_PTR).
    347      1.1  christos    Free the space allocated for it.  */
    348      1.1  christos void
    349      1.1  christos delete_async_event_handler (async_event_handler **async_handler_ptr)
    350      1.1  christos {
    351      1.1  christos   async_event_handler *prev_ptr;
    352      1.1  christos 
    353      1.1  christos   if (async_event_handler_list.first_handler == *async_handler_ptr)
    354      1.1  christos     {
    355      1.1  christos       async_event_handler_list.first_handler
    356      1.1  christos 	= (*async_handler_ptr)->next_handler;
    357      1.1  christos       if (async_event_handler_list.first_handler == NULL)
    358      1.1  christos 	async_event_handler_list.last_handler = NULL;
    359      1.1  christos     }
    360      1.1  christos   else
    361      1.1  christos     {
    362      1.1  christos       prev_ptr = async_event_handler_list.first_handler;
    363      1.1  christos       while (prev_ptr && prev_ptr->next_handler != *async_handler_ptr)
    364      1.1  christos 	prev_ptr = prev_ptr->next_handler;
    365      1.1  christos       gdb_assert (prev_ptr);
    366      1.1  christos       prev_ptr->next_handler = (*async_handler_ptr)->next_handler;
    367      1.1  christos       if (async_event_handler_list.last_handler == (*async_handler_ptr))
    368      1.1  christos 	async_event_handler_list.last_handler = prev_ptr;
    369      1.1  christos     }
    370      1.1  christos   xfree (*async_handler_ptr);
    371      1.1  christos   *async_handler_ptr = NULL;
    372                    }
    373