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