gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / gdb / async-event.c
CommitLineData
93b54c8e 1/* Async events for the GDB event loop.
f7e23710 2 Copyright (C) 1999-2020 Free Software Foundation, Inc.
93b54c8e
TT
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
a1b68f28
SM
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};
93b54c8e
TT
50
51/* PROC is a function to be invoked when the READY flag is set. This
52 happens when the event has been marked with
53 MARK_ASYNC_EVENT_HANDLER. The actual work to be done in response
54 to an event will be carried out by PROC at a later time, within
55 process_event. This provides a deferred execution of event
56 handlers. */
a1b68f28
SM
57struct async_event_handler
58{
59 /* If ready, call this handler from the main event loop, using
60 invoke_event_handler. */
61 int ready;
93b54c8e 62
a1b68f28
SM
63 /* Pointer to next handler. */
64 struct async_event_handler *next_handler;
93b54c8e 65
a1b68f28
SM
66 /* Function to call to do the work. */
67 async_event_handler_func *proc;
93b54c8e 68
a1b68f28
SM
69 /* Argument to PROC. */
70 gdb_client_data client_data;
71};
93b54c8e
TT
72
73/* All the async_signal_handlers gdb is interested in are kept onto
74 this list. */
75static struct
a1b68f28
SM
76{
77 /* Pointer to first in handler list. */
78 async_signal_handler *first_handler;
93b54c8e 79
a1b68f28
SM
80 /* Pointer to last in handler list. */
81 async_signal_handler *last_handler;
82}
93b54c8e
TT
83sighandler_list;
84
85/* All the async_event_handlers gdb is interested in are kept onto
86 this list. */
87static struct
a1b68f28
SM
88{
89 /* Pointer to first in handler list. */
90 async_event_handler *first_handler;
93b54c8e 91
a1b68f28
SM
92 /* Pointer to last in handler list. */
93 async_event_handler *last_handler;
94}
93b54c8e
TT
95async_event_handler_list;
96
97
98/* This event is signalled whenever an asynchronous handler needs to
99 defer an action to the event loop. */
100static struct serial_event *async_signal_handlers_serial_event;
101
102/* Callback registered with ASYNC_SIGNAL_HANDLERS_SERIAL_EVENT. */
103
104static void
105async_signals_handler (int error, gdb_client_data client_data)
106{
107 /* Do nothing. Handlers are run by invoke_async_signal_handlers
108 from instead. */
109}
110
111void
112initialize_async_signal_handlers (void)
113{
114 async_signal_handlers_serial_event = make_serial_event ();
115
116 add_file_handler (serial_event_fd (async_signal_handlers_serial_event),
117 async_signals_handler, NULL);
118}
119
120\f
121
122/* Create an asynchronous handler, allocating memory for it.
123 Return a pointer to the newly created handler.
124 This pointer will be used to invoke the handler by
125 invoke_async_signal_handler.
126 PROC is the function to call with CLIENT_DATA argument
127 whenever the handler is invoked. */
128async_signal_handler *
129create_async_signal_handler (sig_handler_func * proc,
130 gdb_client_data client_data)
131{
132 async_signal_handler *async_handler_ptr;
133
134 async_handler_ptr = XNEW (async_signal_handler);
135 async_handler_ptr->ready = 0;
136 async_handler_ptr->next_handler = NULL;
137 async_handler_ptr->proc = proc;
138 async_handler_ptr->client_data = client_data;
139 if (sighandler_list.first_handler == NULL)
140 sighandler_list.first_handler = async_handler_ptr;
141 else
142 sighandler_list.last_handler->next_handler = async_handler_ptr;
143 sighandler_list.last_handler = async_handler_ptr;
144 return async_handler_ptr;
145}
146
147/* Mark the handler (ASYNC_HANDLER_PTR) as ready. This information
148 will be used when the handlers are invoked, after we have waited
149 for some event. The caller of this function is the interrupt
150 handler associated with a signal. */
151void
152mark_async_signal_handler (async_signal_handler * async_handler_ptr)
153{
154 async_handler_ptr->ready = 1;
155 serial_event_set (async_signal_handlers_serial_event);
156}
157
158/* See event-loop.h. */
159
160void
161clear_async_signal_handler (async_signal_handler *async_handler_ptr)
162{
163 async_handler_ptr->ready = 0;
164}
165
166/* See event-loop.h. */
167
168int
169async_signal_handler_is_marked (async_signal_handler *async_handler_ptr)
170{
171 return async_handler_ptr->ready;
172}
173
174/* Call all the handlers that are ready. Returns true if any was
175 indeed ready. */
176
177int
178invoke_async_signal_handlers (void)
179{
180 async_signal_handler *async_handler_ptr;
181 int any_ready = 0;
182
183 /* We're going to handle all pending signals, so no need to wake up
184 the event loop again the next time around. Note this must be
185 cleared _before_ calling the callbacks, to avoid races. */
186 serial_event_clear (async_signal_handlers_serial_event);
187
188 /* Invoke all ready handlers. */
189
190 while (1)
191 {
192 for (async_handler_ptr = sighandler_list.first_handler;
193 async_handler_ptr != NULL;
194 async_handler_ptr = async_handler_ptr->next_handler)
195 {
196 if (async_handler_ptr->ready)
197 break;
198 }
199 if (async_handler_ptr == NULL)
200 break;
201 any_ready = 1;
202 async_handler_ptr->ready = 0;
203 /* Async signal handlers have no connection to whichever was the
204 current UI, and thus always run on the main one. */
205 current_ui = main_ui;
206 (*async_handler_ptr->proc) (async_handler_ptr->client_data);
207 }
208
209 return any_ready;
210}
211
212/* Delete an asynchronous handler (ASYNC_HANDLER_PTR).
213 Free the space allocated for it. */
214void
215delete_async_signal_handler (async_signal_handler ** async_handler_ptr)
216{
217 async_signal_handler *prev_ptr;
218
219 if (sighandler_list.first_handler == (*async_handler_ptr))
220 {
221 sighandler_list.first_handler = (*async_handler_ptr)->next_handler;
222 if (sighandler_list.first_handler == NULL)
223 sighandler_list.last_handler = NULL;
224 }
225 else
226 {
227 prev_ptr = sighandler_list.first_handler;
228 while (prev_ptr && prev_ptr->next_handler != (*async_handler_ptr))
229 prev_ptr = prev_ptr->next_handler;
230 gdb_assert (prev_ptr);
231 prev_ptr->next_handler = (*async_handler_ptr)->next_handler;
232 if (sighandler_list.last_handler == (*async_handler_ptr))
233 sighandler_list.last_handler = prev_ptr;
234 }
235 xfree ((*async_handler_ptr));
236 (*async_handler_ptr) = NULL;
237}
238
239/* Create an asynchronous event handler, allocating memory for it.
240 Return a pointer to the newly created handler. PROC is the
241 function to call with CLIENT_DATA argument whenever the handler is
242 invoked. */
243async_event_handler *
244create_async_event_handler (async_event_handler_func *proc,
245 gdb_client_data client_data)
246{
247 async_event_handler *h;
248
249 h = XNEW (struct async_event_handler);
250 h->ready = 0;
251 h->next_handler = NULL;
252 h->proc = proc;
253 h->client_data = client_data;
254 if (async_event_handler_list.first_handler == NULL)
255 async_event_handler_list.first_handler = h;
256 else
257 async_event_handler_list.last_handler->next_handler = h;
258 async_event_handler_list.last_handler = h;
259 return h;
260}
261
262/* Mark the handler (ASYNC_HANDLER_PTR) as ready. This information
263 will be used by gdb_do_one_event. The caller will be whoever
264 created the event source, and wants to signal that the event is
265 ready to be handled. */
266void
267mark_async_event_handler (async_event_handler *async_handler_ptr)
268{
269 async_handler_ptr->ready = 1;
270}
271
272/* See event-loop.h. */
273
274void
275clear_async_event_handler (async_event_handler *async_handler_ptr)
276{
277 async_handler_ptr->ready = 0;
278}
279
280/* Check if asynchronous event handlers are ready, and call the
281 handler function for one that is. */
282
283int
284check_async_event_handlers ()
285{
286 async_event_handler *async_handler_ptr;
287
288 for (async_handler_ptr = async_event_handler_list.first_handler;
289 async_handler_ptr != NULL;
290 async_handler_ptr = async_handler_ptr->next_handler)
291 {
292 if (async_handler_ptr->ready)
293 {
294 async_handler_ptr->ready = 0;
295 (*async_handler_ptr->proc) (async_handler_ptr->client_data);
296 return 1;
297 }
298 }
299
300 return 0;
301}
302
303/* Delete an asynchronous handler (ASYNC_HANDLER_PTR).
304 Free the space allocated for it. */
305void
306delete_async_event_handler (async_event_handler **async_handler_ptr)
307{
308 async_event_handler *prev_ptr;
309
310 if (async_event_handler_list.first_handler == *async_handler_ptr)
311 {
312 async_event_handler_list.first_handler
313 = (*async_handler_ptr)->next_handler;
314 if (async_event_handler_list.first_handler == NULL)
315 async_event_handler_list.last_handler = NULL;
316 }
317 else
318 {
319 prev_ptr = async_event_handler_list.first_handler;
320 while (prev_ptr && prev_ptr->next_handler != *async_handler_ptr)
321 prev_ptr = prev_ptr->next_handler;
322 gdb_assert (prev_ptr);
323 prev_ptr->next_handler = (*async_handler_ptr)->next_handler;
324 if (async_event_handler_list.last_handler == (*async_handler_ptr))
325 async_event_handler_list.last_handler = prev_ptr;
326 }
327 xfree (*async_handler_ptr);
328 *async_handler_ptr = NULL;
329}
This page took 0.045311 seconds and 4 git commands to generate.