event-loop.cc revision 1.1.1.2 1 1.1 christos /* Event loop machinery for GDB, the GNU debugger.
2 1.1.1.2 christos Copyright (C) 1999-2023 Free Software Foundation, Inc.
3 1.1 christos Written by Elena Zannoni <ezannoni (at) cygnus.com> of Cygnus Solutions.
4 1.1 christos
5 1.1 christos This file is part of GDB.
6 1.1 christos
7 1.1 christos This program is free software; you can redistribute it and/or modify
8 1.1 christos it under the terms of the GNU General Public License as published by
9 1.1 christos the Free Software Foundation; either version 3 of the License, or
10 1.1 christos (at your option) any later version.
11 1.1 christos
12 1.1 christos This program is distributed in the hope that it will be useful,
13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 1.1 christos GNU General Public License for more details.
16 1.1 christos
17 1.1 christos You should have received a copy of the GNU General Public License
18 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 1.1 christos
20 1.1 christos #include "gdbsupport/common-defs.h"
21 1.1 christos #include "gdbsupport/event-loop.h"
22 1.1 christos
23 1.1 christos #include <chrono>
24 1.1 christos
25 1.1 christos #ifdef HAVE_POLL
26 1.1 christos #if defined (HAVE_POLL_H)
27 1.1 christos #include <poll.h>
28 1.1 christos #elif defined (HAVE_SYS_POLL_H)
29 1.1 christos #include <sys/poll.h>
30 1.1 christos #endif
31 1.1 christos #endif
32 1.1 christos
33 1.1 christos #include <sys/types.h>
34 1.1 christos #include "gdbsupport/gdb_sys_time.h"
35 1.1 christos #include "gdbsupport/gdb_select.h"
36 1.1.1.2 christos #include "gdbsupport/gdb_optional.h"
37 1.1.1.2 christos #include "gdbsupport/scope-exit.h"
38 1.1.1.2 christos
39 1.1.1.2 christos /* See event-loop.h. */
40 1.1.1.2 christos
41 1.1.1.2 christos debug_event_loop_kind debug_event_loop;
42 1.1 christos
43 1.1 christos /* Tell create_file_handler what events we are interested in.
44 1.1 christos This is used by the select version of the event loop. */
45 1.1 christos
46 1.1 christos #define GDB_READABLE (1<<1)
47 1.1 christos #define GDB_WRITABLE (1<<2)
48 1.1 christos #define GDB_EXCEPTION (1<<3)
49 1.1 christos
50 1.1 christos /* Information about each file descriptor we register with the event
51 1.1 christos loop. */
52 1.1 christos
53 1.1.1.2 christos struct file_handler
54 1.1.1.2 christos {
55 1.1.1.2 christos /* File descriptor. */
56 1.1.1.2 christos int fd;
57 1.1 christos
58 1.1.1.2 christos /* Events we want to monitor: POLLIN, etc. */
59 1.1.1.2 christos int mask;
60 1.1.1.2 christos
61 1.1.1.2 christos /* Events that have been seen since the last time. */
62 1.1.1.2 christos int ready_mask;
63 1.1.1.2 christos
64 1.1.1.2 christos /* Procedure to call when fd is ready. */
65 1.1.1.2 christos handler_func *proc;
66 1.1.1.2 christos
67 1.1.1.2 christos /* Argument to pass to proc. */
68 1.1.1.2 christos gdb_client_data client_data;
69 1.1 christos
70 1.1.1.2 christos /* User-friendly name of this handler. */
71 1.1.1.2 christos std::string name;
72 1.1.1.2 christos
73 1.1.1.2 christos /* If set, this file descriptor is used for a user interface. */
74 1.1.1.2 christos bool is_ui;
75 1.1.1.2 christos
76 1.1.1.2 christos /* Was an error detected on this fd? */
77 1.1.1.2 christos int error;
78 1.1.1.2 christos
79 1.1.1.2 christos /* Next registered file descriptor. */
80 1.1.1.2 christos struct file_handler *next_file;
81 1.1.1.2 christos };
82 1.1.1.2 christos
83 1.1.1.2 christos #ifdef HAVE_POLL
84 1.1.1.2 christos /* Do we use poll or select? Some systems have poll, but then it's
85 1.1.1.2 christos not useable with all kinds of files. We probe that whenever a new
86 1.1.1.2 christos file handler is added. */
87 1.1.1.2 christos static bool use_poll = true;
88 1.1.1.2 christos #endif
89 1.1 christos
90 1.1 christos #ifdef USE_WIN32API
91 1.1 christos #include <windows.h>
92 1.1 christos #include <io.h>
93 1.1 christos #endif
94 1.1 christos
95 1.1 christos /* Gdb_notifier is just a list of file descriptors gdb is interested in.
96 1.1 christos These are the input file descriptor, and the target file
97 1.1 christos descriptor. We have two flavors of the notifier, one for platforms
98 1.1 christos that have the POLL function, the other for those that don't, and
99 1.1 christos only support SELECT. Each of the elements in the gdb_notifier list is
100 1.1 christos basically a description of what kind of events gdb is interested
101 1.1 christos in, for each fd. */
102 1.1 christos
103 1.1 christos static struct
104 1.1 christos {
105 1.1 christos /* Ptr to head of file handler list. */
106 1.1 christos file_handler *first_file_handler;
107 1.1 christos
108 1.1 christos /* Next file handler to handle, for the select variant. To level
109 1.1 christos the fairness across event sources, we serve file handlers in a
110 1.1 christos round-robin-like fashion. The number and order of the polled
111 1.1 christos file handlers may change between invocations, but this is good
112 1.1 christos enough. */
113 1.1 christos file_handler *next_file_handler;
114 1.1 christos
115 1.1 christos #ifdef HAVE_POLL
116 1.1 christos /* Ptr to array of pollfd structures. */
117 1.1 christos struct pollfd *poll_fds;
118 1.1 christos
119 1.1 christos /* Next file descriptor to handle, for the poll variant. To level
120 1.1 christos the fairness across event sources, we poll the file descriptors
121 1.1 christos in a round-robin-like fashion. The number and order of the
122 1.1 christos polled file descriptors may change between invocations, but
123 1.1 christos this is good enough. */
124 1.1 christos int next_poll_fds_index;
125 1.1 christos
126 1.1 christos /* Timeout in milliseconds for calls to poll(). */
127 1.1 christos int poll_timeout;
128 1.1 christos #endif
129 1.1 christos
130 1.1 christos /* Masks to be used in the next call to select.
131 1.1 christos Bits are set in response to calls to create_file_handler. */
132 1.1 christos fd_set check_masks[3];
133 1.1 christos
134 1.1 christos /* What file descriptors were found ready by select. */
135 1.1 christos fd_set ready_masks[3];
136 1.1 christos
137 1.1 christos /* Number of file descriptors to monitor (for poll). */
138 1.1 christos /* Number of valid bits (highest fd value + 1) (for select). */
139 1.1 christos int num_fds;
140 1.1 christos
141 1.1 christos /* Time structure for calls to select(). */
142 1.1 christos struct timeval select_timeout;
143 1.1 christos
144 1.1 christos /* Flag to tell whether the timeout should be used. */
145 1.1 christos int timeout_valid;
146 1.1 christos }
147 1.1 christos gdb_notifier;
148 1.1 christos
149 1.1 christos /* Structure associated with a timer. PROC will be executed at the
150 1.1 christos first occasion after WHEN. */
151 1.1 christos struct gdb_timer
152 1.1 christos {
153 1.1 christos std::chrono::steady_clock::time_point when;
154 1.1 christos int timer_id;
155 1.1 christos struct gdb_timer *next;
156 1.1 christos timer_handler_func *proc; /* Function to call to do the work. */
157 1.1 christos gdb_client_data client_data; /* Argument to async_handler_func. */
158 1.1 christos };
159 1.1 christos
160 1.1 christos /* List of currently active timers. It is sorted in order of
161 1.1 christos increasing timers. */
162 1.1 christos static struct
163 1.1 christos {
164 1.1 christos /* Pointer to first in timer list. */
165 1.1 christos struct gdb_timer *first_timer;
166 1.1 christos
167 1.1 christos /* Id of the last timer created. */
168 1.1 christos int num_timers;
169 1.1 christos }
170 1.1 christos timer_list;
171 1.1 christos
172 1.1 christos static void create_file_handler (int fd, int mask, handler_func *proc,
173 1.1.1.2 christos gdb_client_data client_data,
174 1.1.1.2 christos std::string &&name, bool is_ui);
175 1.1 christos static int gdb_wait_for_event (int);
176 1.1 christos static int update_wait_timeout (void);
177 1.1 christos static int poll_timers (void);
178 1.1 christos
179 1.1 christos /* Process one high level event. If nothing is ready at this time,
181 1.1.1.2 christos wait at most MSTIMEOUT milliseconds for something to happen (via
182 1.1.1.2 christos gdb_wait_for_event), then process it. Returns >0 if something was
183 1.1.1.2 christos done, <0 if there are no event sources to wait for, =0 if timeout occurred.
184 1.1.1.2 christos A timeout of 0 allows to serve an already pending event, but does not
185 1.1.1.2 christos wait if none found.
186 1.1.1.2 christos Setting the timeout to a negative value disables it.
187 1.1.1.2 christos The timeout is never used by gdb itself, it is however needed to
188 1.1 christos integrate gdb event handling within Insight's GUI event loop. */
189 1.1 christos
190 1.1.1.2 christos int
191 1.1 christos gdb_do_one_event (int mstimeout)
192 1.1 christos {
193 1.1 christos static int event_source_head = 0;
194 1.1 christos const int number_of_sources = 3;
195 1.1 christos int current = 0;
196 1.1 christos
197 1.1 christos /* First let's see if there are any asynchronous signal handlers
198 1.1 christos that are ready. These would be the result of invoking any of the
199 1.1 christos signal handlers. */
200 1.1 christos if (invoke_async_signal_handlers ())
201 1.1 christos return 1;
202 1.1 christos
203 1.1 christos /* To level the fairness across event sources, we poll them in a
204 1.1 christos round-robin fashion. */
205 1.1 christos for (current = 0; current < number_of_sources; current++)
206 1.1 christos {
207 1.1 christos int res;
208 1.1 christos
209 1.1 christos switch (event_source_head)
210 1.1 christos {
211 1.1 christos case 0:
212 1.1 christos /* Are any timers that are ready? */
213 1.1 christos res = poll_timers ();
214 1.1 christos break;
215 1.1 christos case 1:
216 1.1 christos /* Are there events already waiting to be collected on the
217 1.1 christos monitored file descriptors? */
218 1.1 christos res = gdb_wait_for_event (0);
219 1.1 christos break;
220 1.1 christos case 2:
221 1.1 christos /* Are there any asynchronous event handlers ready? */
222 1.1 christos res = check_async_event_handlers ();
223 1.1 christos break;
224 1.1.1.2 christos default:
225 1.1 christos internal_error ("unexpected event_source_head %d",
226 1.1 christos event_source_head);
227 1.1 christos }
228 1.1 christos
229 1.1 christos event_source_head++;
230 1.1 christos if (event_source_head == number_of_sources)
231 1.1 christos event_source_head = 0;
232 1.1 christos
233 1.1 christos if (res > 0)
234 1.1 christos return 1;
235 1.1 christos }
236 1.1.1.2 christos
237 1.1.1.2 christos if (mstimeout == 0)
238 1.1.1.2 christos return 0; /* 0ms timeout: do not wait for an event. */
239 1.1 christos
240 1.1 christos /* Block waiting for a new event. If gdb_wait_for_event returns -1,
241 1.1 christos we should get out because this means that there are no event
242 1.1.1.2 christos sources left. This will make the event loop stop, and the
243 1.1.1.2 christos application exit.
244 1.1.1.2 christos If a timeout has been given, a new timer is set accordingly
245 1.1.1.2 christos to abort event wait. It is deleted upon gdb_wait_for_event
246 1.1.1.2 christos termination and thus should never be triggered.
247 1.1.1.2 christos When the timeout is reached, events are not monitored again:
248 1.1.1.2 christos they already have been checked in the loop above. */
249 1.1.1.2 christos
250 1.1.1.2 christos gdb::optional<int> timer_id;
251 1.1.1.2 christos
252 1.1.1.2 christos SCOPE_EXIT
253 1.1.1.2 christos {
254 1.1.1.2 christos if (timer_id.has_value ())
255 1.1.1.2 christos delete_timer (*timer_id);
256 1.1.1.2 christos };
257 1.1.1.2 christos
258 1.1.1.2 christos if (mstimeout > 0)
259 1.1.1.2 christos timer_id = create_timer (mstimeout,
260 1.1.1.2 christos [] (gdb_client_data arg)
261 1.1.1.2 christos {
262 1.1.1.2 christos ((gdb::optional<int> *) arg)->reset ();
263 1.1.1.2 christos },
264 1.1.1.2 christos &timer_id);
265 1.1 christos return gdb_wait_for_event (1);
266 1.1 christos }
267 1.1.1.2 christos
268 1.1 christos /* See event-loop.h */
269 1.1 christos
270 1.1.1.2 christos void
271 1.1.1.2 christos add_file_handler (int fd, handler_func *proc, gdb_client_data client_data,
272 1.1 christos std::string &&name, bool is_ui)
273 1.1 christos {
274 1.1 christos #ifdef HAVE_POLL
275 1.1 christos if (use_poll)
276 1.1.1.2 christos {
277 1.1.1.2 christos struct pollfd fds;
278 1.1 christos
279 1.1.1.2 christos /* Check to see if poll () is usable. If not, we'll switch to
280 1.1.1.2 christos use select. This can happen on systems like
281 1.1.1.2 christos m68k-motorola-sys, `poll' cannot be used to wait for `stdin'.
282 1.1.1.2 christos On m68k-motorola-sysv, tty's are not stream-based and not
283 1.1 christos `poll'able. */
284 1.1 christos fds.fd = fd;
285 1.1 christos fds.events = POLLIN;
286 1.1.1.2 christos if (poll (&fds, 1, 0) == 1 && (fds.revents & POLLNVAL))
287 1.1 christos use_poll = false;
288 1.1 christos }
289 1.1 christos if (use_poll)
290 1.1.1.2 christos {
291 1.1.1.2 christos create_file_handler (fd, POLLIN, proc, client_data, std::move (name),
292 1.1 christos is_ui);
293 1.1 christos }
294 1.1.1.2 christos else
295 1.1.1.2 christos #endif /* HAVE_POLL */
296 1.1.1.2 christos create_file_handler (fd, GDB_READABLE | GDB_EXCEPTION,
297 1.1 christos proc, client_data, std::move (name), is_ui);
298 1.1 christos }
299 1.1.1.2 christos
300 1.1 christos /* Helper for add_file_handler.
301 1.1 christos
302 1.1 christos For the poll case, MASK is a combination (OR) of POLLIN,
303 1.1 christos POLLRDNORM, POLLRDBAND, POLLPRI, POLLOUT, POLLWRNORM, POLLWRBAND:
304 1.1 christos these are the events we are interested in. If any of them occurs,
305 1.1 christos proc should be called.
306 1.1 christos
307 1.1 christos For the select case, MASK is a combination of READABLE, WRITABLE,
308 1.1 christos EXCEPTION. PROC is the procedure that will be called when an event
309 1.1 christos occurs for FD. CLIENT_DATA is the argument to pass to PROC. */
310 1.1 christos
311 1.1.1.2 christos static void
312 1.1.1.2 christos create_file_handler (int fd, int mask, handler_func * proc,
313 1.1.1.2 christos gdb_client_data client_data, std::string &&name,
314 1.1 christos bool is_ui)
315 1.1 christos {
316 1.1 christos file_handler *file_ptr;
317 1.1 christos
318 1.1 christos /* Do we already have a file handler for this file? (We may be
319 1.1 christos changing its associated procedure). */
320 1.1 christos for (file_ptr = gdb_notifier.first_file_handler; file_ptr != NULL;
321 1.1 christos file_ptr = file_ptr->next_file)
322 1.1 christos {
323 1.1 christos if (file_ptr->fd == fd)
324 1.1 christos break;
325 1.1 christos }
326 1.1 christos
327 1.1 christos /* It is a new file descriptor. Add it to the list. Otherwise, just
328 1.1 christos change the data associated with it. */
329 1.1 christos if (file_ptr == NULL)
330 1.1.1.2 christos {
331 1.1 christos file_ptr = new file_handler;
332 1.1 christos file_ptr->fd = fd;
333 1.1 christos file_ptr->ready_mask = 0;
334 1.1 christos file_ptr->next_file = gdb_notifier.first_file_handler;
335 1.1 christos gdb_notifier.first_file_handler = file_ptr;
336 1.1.1.2 christos
337 1.1 christos #ifdef HAVE_POLL
338 1.1 christos if (use_poll)
339 1.1 christos {
340 1.1 christos gdb_notifier.num_fds++;
341 1.1 christos if (gdb_notifier.poll_fds)
342 1.1 christos gdb_notifier.poll_fds =
343 1.1 christos (struct pollfd *) xrealloc (gdb_notifier.poll_fds,
344 1.1 christos (gdb_notifier.num_fds
345 1.1 christos * sizeof (struct pollfd)));
346 1.1 christos else
347 1.1 christos gdb_notifier.poll_fds =
348 1.1 christos XNEW (struct pollfd);
349 1.1 christos (gdb_notifier.poll_fds + gdb_notifier.num_fds - 1)->fd = fd;
350 1.1 christos (gdb_notifier.poll_fds + gdb_notifier.num_fds - 1)->events = mask;
351 1.1 christos (gdb_notifier.poll_fds + gdb_notifier.num_fds - 1)->revents = 0;
352 1.1 christos }
353 1.1.1.2 christos else
354 1.1 christos #endif /* HAVE_POLL */
355 1.1 christos {
356 1.1 christos if (mask & GDB_READABLE)
357 1.1 christos FD_SET (fd, &gdb_notifier.check_masks[0]);
358 1.1 christos else
359 1.1 christos FD_CLR (fd, &gdb_notifier.check_masks[0]);
360 1.1 christos
361 1.1 christos if (mask & GDB_WRITABLE)
362 1.1 christos FD_SET (fd, &gdb_notifier.check_masks[1]);
363 1.1 christos else
364 1.1 christos FD_CLR (fd, &gdb_notifier.check_masks[1]);
365 1.1 christos
366 1.1 christos if (mask & GDB_EXCEPTION)
367 1.1 christos FD_SET (fd, &gdb_notifier.check_masks[2]);
368 1.1 christos else
369 1.1 christos FD_CLR (fd, &gdb_notifier.check_masks[2]);
370 1.1 christos
371 1.1 christos if (gdb_notifier.num_fds <= fd)
372 1.1 christos gdb_notifier.num_fds = fd + 1;
373 1.1 christos }
374 1.1 christos }
375 1.1 christos
376 1.1 christos file_ptr->proc = proc;
377 1.1 christos file_ptr->client_data = client_data;
378 1.1.1.2 christos file_ptr->mask = mask;
379 1.1.1.2 christos file_ptr->name = std::move (name);
380 1.1 christos file_ptr->is_ui = is_ui;
381 1.1 christos }
382 1.1 christos
383 1.1 christos /* Return the next file handler to handle, and advance to the next
384 1.1 christos file handler, wrapping around if the end of the list is
385 1.1 christos reached. */
386 1.1 christos
387 1.1 christos static file_handler *
388 1.1 christos get_next_file_handler_to_handle_and_advance (void)
389 1.1 christos {
390 1.1 christos file_handler *curr_next;
391 1.1 christos
392 1.1 christos /* The first time around, this is still NULL. */
393 1.1 christos if (gdb_notifier.next_file_handler == NULL)
394 1.1 christos gdb_notifier.next_file_handler = gdb_notifier.first_file_handler;
395 1.1 christos
396 1.1 christos curr_next = gdb_notifier.next_file_handler;
397 1.1 christos gdb_assert (curr_next != NULL);
398 1.1 christos
399 1.1 christos /* Advance. */
400 1.1 christos gdb_notifier.next_file_handler = curr_next->next_file;
401 1.1 christos /* Wrap around, if necessary. */
402 1.1 christos if (gdb_notifier.next_file_handler == NULL)
403 1.1 christos gdb_notifier.next_file_handler = gdb_notifier.first_file_handler;
404 1.1 christos
405 1.1 christos return curr_next;
406 1.1 christos }
407 1.1 christos
408 1.1 christos /* Remove the file descriptor FD from the list of monitored fd's:
409 1.1 christos i.e. we don't care anymore about events on the FD. */
410 1.1 christos void
411 1.1 christos delete_file_handler (int fd)
412 1.1 christos {
413 1.1 christos file_handler *file_ptr, *prev_ptr = NULL;
414 1.1 christos int i;
415 1.1 christos
416 1.1 christos /* Find the entry for the given file. */
417 1.1 christos
418 1.1 christos for (file_ptr = gdb_notifier.first_file_handler; file_ptr != NULL;
419 1.1 christos file_ptr = file_ptr->next_file)
420 1.1 christos {
421 1.1 christos if (file_ptr->fd == fd)
422 1.1 christos break;
423 1.1 christos }
424 1.1 christos
425 1.1 christos if (file_ptr == NULL)
426 1.1 christos return;
427 1.1.1.2 christos
428 1.1 christos #ifdef HAVE_POLL
429 1.1 christos if (use_poll)
430 1.1.1.2 christos {
431 1.1.1.2 christos int j;
432 1.1.1.2 christos struct pollfd *new_poll_fds;
433 1.1 christos
434 1.1.1.2 christos /* Create a new poll_fds array by copying every fd's information
435 1.1 christos but the one we want to get rid of. */
436 1.1 christos
437 1.1 christos new_poll_fds = (struct pollfd *)
438 1.1 christos xmalloc ((gdb_notifier.num_fds - 1) * sizeof (struct pollfd));
439 1.1 christos
440 1.1 christos for (i = 0, j = 0; i < gdb_notifier.num_fds; i++)
441 1.1 christos {
442 1.1 christos if ((gdb_notifier.poll_fds + i)->fd != fd)
443 1.1 christos {
444 1.1 christos (new_poll_fds + j)->fd = (gdb_notifier.poll_fds + i)->fd;
445 1.1 christos (new_poll_fds + j)->events = (gdb_notifier.poll_fds + i)->events;
446 1.1 christos (new_poll_fds + j)->revents
447 1.1 christos = (gdb_notifier.poll_fds + i)->revents;
448 1.1 christos j++;
449 1.1 christos }
450 1.1 christos }
451 1.1 christos xfree (gdb_notifier.poll_fds);
452 1.1 christos gdb_notifier.poll_fds = new_poll_fds;
453 1.1 christos gdb_notifier.num_fds--;
454 1.1 christos }
455 1.1.1.2 christos else
456 1.1 christos #endif /* HAVE_POLL */
457 1.1 christos {
458 1.1 christos if (file_ptr->mask & GDB_READABLE)
459 1.1 christos FD_CLR (fd, &gdb_notifier.check_masks[0]);
460 1.1 christos if (file_ptr->mask & GDB_WRITABLE)
461 1.1 christos FD_CLR (fd, &gdb_notifier.check_masks[1]);
462 1.1 christos if (file_ptr->mask & GDB_EXCEPTION)
463 1.1 christos FD_CLR (fd, &gdb_notifier.check_masks[2]);
464 1.1 christos
465 1.1 christos /* Find current max fd. */
466 1.1 christos
467 1.1 christos if ((fd + 1) == gdb_notifier.num_fds)
468 1.1 christos {
469 1.1 christos gdb_notifier.num_fds--;
470 1.1 christos for (i = gdb_notifier.num_fds; i; i--)
471 1.1 christos {
472 1.1 christos if (FD_ISSET (i - 1, &gdb_notifier.check_masks[0])
473 1.1 christos || FD_ISSET (i - 1, &gdb_notifier.check_masks[1])
474 1.1 christos || FD_ISSET (i - 1, &gdb_notifier.check_masks[2]))
475 1.1 christos break;
476 1.1 christos }
477 1.1 christos gdb_notifier.num_fds = i;
478 1.1 christos }
479 1.1 christos }
480 1.1 christos
481 1.1 christos /* Deactivate the file descriptor, by clearing its mask,
482 1.1 christos so that it will not fire again. */
483 1.1 christos
484 1.1 christos file_ptr->mask = 0;
485 1.1 christos
486 1.1 christos /* If this file handler was going to be the next one to be handled,
487 1.1 christos advance to the next's next, if any. */
488 1.1 christos if (gdb_notifier.next_file_handler == file_ptr)
489 1.1 christos {
490 1.1 christos if (file_ptr->next_file == NULL
491 1.1 christos && file_ptr == gdb_notifier.first_file_handler)
492 1.1 christos gdb_notifier.next_file_handler = NULL;
493 1.1 christos else
494 1.1 christos get_next_file_handler_to_handle_and_advance ();
495 1.1 christos }
496 1.1 christos
497 1.1 christos /* Get rid of the file handler in the file handler list. */
498 1.1 christos if (file_ptr == gdb_notifier.first_file_handler)
499 1.1 christos gdb_notifier.first_file_handler = file_ptr->next_file;
500 1.1 christos else
501 1.1 christos {
502 1.1 christos for (prev_ptr = gdb_notifier.first_file_handler;
503 1.1 christos prev_ptr->next_file != file_ptr;
504 1.1 christos prev_ptr = prev_ptr->next_file)
505 1.1 christos ;
506 1.1 christos prev_ptr->next_file = file_ptr->next_file;
507 1.1.1.2 christos }
508 1.1.1.2 christos
509 1.1 christos delete file_ptr;
510 1.1 christos }
511 1.1 christos
512 1.1 christos /* Handle the given event by calling the procedure associated to the
513 1.1 christos corresponding file handler. */
514 1.1 christos
515 1.1 christos static void
516 1.1 christos handle_file_event (file_handler *file_ptr, int ready_mask)
517 1.1 christos {
518 1.1 christos int mask;
519 1.1.1.2 christos
520 1.1.1.2 christos /* See if the desired events (mask) match the received events
521 1.1 christos (ready_mask). */
522 1.1 christos
523 1.1.1.2 christos #ifdef HAVE_POLL
524 1.1.1.2 christos if (use_poll)
525 1.1.1.2 christos {
526 1.1 christos int error_mask;
527 1.1.1.2 christos
528 1.1.1.2 christos /* With poll, the ready_mask could have any of three events set
529 1.1.1.2 christos to 1: POLLHUP, POLLERR, POLLNVAL. These events cannot be
530 1.1.1.2 christos used in the requested event mask (events), but they can be
531 1.1.1.2 christos returned in the return mask (revents). We need to check for
532 1.1.1.2 christos those event too, and add them to the mask which will be
533 1.1.1.2 christos passed to the handler. */
534 1.1.1.2 christos
535 1.1.1.2 christos /* POLLHUP means EOF, but can be combined with POLLIN to
536 1.1.1.2 christos signal more data to read. */
537 1.1.1.2 christos error_mask = POLLHUP | POLLERR | POLLNVAL;
538 1.1.1.2 christos mask = ready_mask & (file_ptr->mask | error_mask);
539 1.1.1.2 christos
540 1.1.1.2 christos if ((mask & (POLLERR | POLLNVAL)) != 0)
541 1.1.1.2 christos {
542 1.1.1.2 christos /* Work in progress. We may need to tell somebody
543 1.1.1.2 christos what kind of error we had. */
544 1.1.1.2 christos if (mask & POLLERR)
545 1.1.1.2 christos warning (_("Error detected on fd %d"), file_ptr->fd);
546 1.1.1.2 christos if (mask & POLLNVAL)
547 1.1.1.2 christos warning (_("Invalid or non-`poll'able fd %d"),
548 1.1.1.2 christos file_ptr->fd);
549 1.1.1.2 christos file_ptr->error = 1;
550 1.1.1.2 christos }
551 1.1.1.2 christos else
552 1.1.1.2 christos file_ptr->error = 0;
553 1.1.1.2 christos }
554 1.1.1.2 christos else
555 1.1.1.2 christos #endif /* HAVE_POLL */
556 1.1.1.2 christos {
557 1.1.1.2 christos if (ready_mask & GDB_EXCEPTION)
558 1.1.1.2 christos {
559 1.1.1.2 christos warning (_("Exception condition detected on fd %d"),
560 1.1.1.2 christos file_ptr->fd);
561 1.1 christos file_ptr->error = 1;
562 1.1.1.2 christos }
563 1.1.1.2 christos else
564 1.1.1.2 christos file_ptr->error = 0;
565 1.1.1.2 christos mask = ready_mask & file_ptr->mask;
566 1.1.1.2 christos }
567 1.1.1.2 christos
568 1.1.1.2 christos /* If there was a match, then call the handler. */
569 1.1.1.2 christos if (mask != 0)
570 1.1.1.2 christos {
571 1.1.1.2 christos event_loop_ui_debug_printf (file_ptr->is_ui,
572 1.1.1.2 christos "invoking fd file handler `%s`",
573 1.1.1.2 christos file_ptr->name.c_str ());
574 1.1 christos file_ptr->proc (file_ptr->error, file_ptr->client_data);
575 1.1 christos }
576 1.1 christos }
577 1.1 christos
578 1.1 christos /* Wait for new events on the monitored file descriptors. Run the
579 1.1 christos event handler if the first descriptor that is detected by the poll.
580 1.1 christos If BLOCK and if there are no events, this function will block in
581 1.1 christos the call to poll. Return 1 if an event was handled. Return -1 if
582 1.1 christos there are no file descriptors to monitor. Return 1 if an event was
583 1.1 christos handled, otherwise returns 0. */
584 1.1 christos
585 1.1 christos static int
586 1.1 christos gdb_wait_for_event (int block)
587 1.1 christos {
588 1.1 christos file_handler *file_ptr;
589 1.1 christos int num_found = 0;
590 1.1 christos
591 1.1 christos /* Make sure all output is done before getting another event. */
592 1.1 christos flush_streams ();
593 1.1 christos
594 1.1 christos if (gdb_notifier.num_fds == 0)
595 1.1 christos return -1;
596 1.1 christos
597 1.1 christos if (block)
598 1.1 christos update_wait_timeout ();
599 1.1.1.2 christos
600 1.1 christos #ifdef HAVE_POLL
601 1.1 christos if (use_poll)
602 1.1 christos {
603 1.1 christos int timeout;
604 1.1 christos
605 1.1 christos if (block)
606 1.1 christos timeout = gdb_notifier.timeout_valid ? gdb_notifier.poll_timeout : -1;
607 1.1 christos else
608 1.1 christos timeout = 0;
609 1.1 christos
610 1.1 christos num_found = poll (gdb_notifier.poll_fds,
611 1.1 christos (unsigned long) gdb_notifier.num_fds, timeout);
612 1.1 christos
613 1.1 christos /* Don't print anything if we get out of poll because of a
614 1.1 christos signal. */
615 1.1 christos if (num_found == -1 && errno != EINTR)
616 1.1 christos perror_with_name (("poll"));
617 1.1 christos }
618 1.1.1.2 christos else
619 1.1 christos #endif /* HAVE_POLL */
620 1.1 christos {
621 1.1 christos struct timeval select_timeout;
622 1.1 christos struct timeval *timeout_p;
623 1.1 christos
624 1.1 christos if (block)
625 1.1 christos timeout_p = gdb_notifier.timeout_valid
626 1.1 christos ? &gdb_notifier.select_timeout : NULL;
627 1.1 christos else
628 1.1 christos {
629 1.1 christos memset (&select_timeout, 0, sizeof (select_timeout));
630 1.1 christos timeout_p = &select_timeout;
631 1.1 christos }
632 1.1 christos
633 1.1 christos gdb_notifier.ready_masks[0] = gdb_notifier.check_masks[0];
634 1.1 christos gdb_notifier.ready_masks[1] = gdb_notifier.check_masks[1];
635 1.1 christos gdb_notifier.ready_masks[2] = gdb_notifier.check_masks[2];
636 1.1 christos num_found = gdb_select (gdb_notifier.num_fds,
637 1.1 christos &gdb_notifier.ready_masks[0],
638 1.1 christos &gdb_notifier.ready_masks[1],
639 1.1 christos &gdb_notifier.ready_masks[2],
640 1.1 christos timeout_p);
641 1.1 christos
642 1.1 christos /* Clear the masks after an error from select. */
643 1.1 christos if (num_found == -1)
644 1.1 christos {
645 1.1 christos FD_ZERO (&gdb_notifier.ready_masks[0]);
646 1.1 christos FD_ZERO (&gdb_notifier.ready_masks[1]);
647 1.1 christos FD_ZERO (&gdb_notifier.ready_masks[2]);
648 1.1 christos
649 1.1 christos /* Dont print anything if we got a signal, let gdb handle
650 1.1 christos it. */
651 1.1 christos if (errno != EINTR)
652 1.1 christos perror_with_name (("select"));
653 1.1 christos }
654 1.1 christos }
655 1.1 christos
656 1.1 christos /* Avoid looking at poll_fds[i]->revents if no event fired. */
657 1.1 christos if (num_found <= 0)
658 1.1 christos return 0;
659 1.1 christos
660 1.1 christos /* Run event handlers. We always run just one handler and go back
661 1.1 christos to polling, in case a handler changes the notifier list. Since
662 1.1 christos events for sources we haven't consumed yet wake poll/select
663 1.1 christos immediately, no event is lost. */
664 1.1 christos
665 1.1 christos /* To level the fairness across event descriptors, we handle them in
666 1.1 christos a round-robin-like fashion. The number and order of descriptors
667 1.1.1.2 christos may change between invocations, but this is good enough. */
668 1.1 christos #ifdef HAVE_POLL
669 1.1 christos if (use_poll)
670 1.1 christos {
671 1.1 christos int i;
672 1.1 christos int mask;
673 1.1 christos
674 1.1 christos while (1)
675 1.1 christos {
676 1.1 christos if (gdb_notifier.next_poll_fds_index >= gdb_notifier.num_fds)
677 1.1 christos gdb_notifier.next_poll_fds_index = 0;
678 1.1 christos i = gdb_notifier.next_poll_fds_index++;
679 1.1 christos
680 1.1 christos gdb_assert (i < gdb_notifier.num_fds);
681 1.1 christos if ((gdb_notifier.poll_fds + i)->revents)
682 1.1 christos break;
683 1.1 christos }
684 1.1 christos
685 1.1 christos for (file_ptr = gdb_notifier.first_file_handler;
686 1.1 christos file_ptr != NULL;
687 1.1 christos file_ptr = file_ptr->next_file)
688 1.1 christos {
689 1.1 christos if (file_ptr->fd == (gdb_notifier.poll_fds + i)->fd)
690 1.1 christos break;
691 1.1 christos }
692 1.1 christos gdb_assert (file_ptr != NULL);
693 1.1 christos
694 1.1 christos mask = (gdb_notifier.poll_fds + i)->revents;
695 1.1 christos handle_file_event (file_ptr, mask);
696 1.1 christos return 1;
697 1.1 christos }
698 1.1.1.2 christos else
699 1.1 christos #endif /* HAVE_POLL */
700 1.1 christos {
701 1.1 christos /* See comment about even source fairness above. */
702 1.1 christos int mask = 0;
703 1.1 christos
704 1.1 christos do
705 1.1 christos {
706 1.1 christos file_ptr = get_next_file_handler_to_handle_and_advance ();
707 1.1 christos
708 1.1 christos if (FD_ISSET (file_ptr->fd, &gdb_notifier.ready_masks[0]))
709 1.1 christos mask |= GDB_READABLE;
710 1.1 christos if (FD_ISSET (file_ptr->fd, &gdb_notifier.ready_masks[1]))
711 1.1 christos mask |= GDB_WRITABLE;
712 1.1 christos if (FD_ISSET (file_ptr->fd, &gdb_notifier.ready_masks[2]))
713 1.1 christos mask |= GDB_EXCEPTION;
714 1.1 christos }
715 1.1 christos while (mask == 0);
716 1.1 christos
717 1.1 christos handle_file_event (file_ptr, mask);
718 1.1 christos return 1;
719 1.1 christos }
720 1.1 christos return 0;
721 1.1 christos }
722 1.1 christos
723 1.1 christos /* Create a timer that will expire in MS milliseconds from now. When
725 1.1 christos the timer is ready, PROC will be executed. At creation, the timer
726 1.1 christos is added to the timers queue. This queue is kept sorted in order
727 1.1 christos of increasing timers. Return a handle to the timer struct. */
728 1.1 christos
729 1.1 christos int
730 1.1 christos create_timer (int ms, timer_handler_func *proc,
731 1.1 christos gdb_client_data client_data)
732 1.1 christos {
733 1.1 christos using namespace std::chrono;
734 1.1 christos struct gdb_timer *timer_ptr, *timer_index, *prev_timer;
735 1.1 christos
736 1.1 christos steady_clock::time_point time_now = steady_clock::now ();
737 1.1 christos
738 1.1 christos timer_ptr = new gdb_timer ();
739 1.1 christos timer_ptr->when = time_now + milliseconds (ms);
740 1.1 christos timer_ptr->proc = proc;
741 1.1 christos timer_ptr->client_data = client_data;
742 1.1 christos timer_list.num_timers++;
743 1.1 christos timer_ptr->timer_id = timer_list.num_timers;
744 1.1 christos
745 1.1 christos /* Now add the timer to the timer queue, making sure it is sorted in
746 1.1 christos increasing order of expiration. */
747 1.1 christos
748 1.1 christos for (timer_index = timer_list.first_timer;
749 1.1 christos timer_index != NULL;
750 1.1 christos timer_index = timer_index->next)
751 1.1 christos {
752 1.1 christos if (timer_index->when > timer_ptr->when)
753 1.1 christos break;
754 1.1 christos }
755 1.1 christos
756 1.1 christos if (timer_index == timer_list.first_timer)
757 1.1 christos {
758 1.1 christos timer_ptr->next = timer_list.first_timer;
759 1.1 christos timer_list.first_timer = timer_ptr;
760 1.1 christos
761 1.1 christos }
762 1.1 christos else
763 1.1 christos {
764 1.1 christos for (prev_timer = timer_list.first_timer;
765 1.1 christos prev_timer->next != timer_index;
766 1.1 christos prev_timer = prev_timer->next)
767 1.1 christos ;
768 1.1 christos
769 1.1 christos prev_timer->next = timer_ptr;
770 1.1 christos timer_ptr->next = timer_index;
771 1.1 christos }
772 1.1 christos
773 1.1 christos gdb_notifier.timeout_valid = 0;
774 1.1 christos return timer_ptr->timer_id;
775 1.1 christos }
776 1.1 christos
777 1.1 christos /* There is a chance that the creator of the timer wants to get rid of
778 1.1 christos it before it expires. */
779 1.1 christos void
780 1.1 christos delete_timer (int id)
781 1.1 christos {
782 1.1 christos struct gdb_timer *timer_ptr, *prev_timer = NULL;
783 1.1 christos
784 1.1 christos /* Find the entry for the given timer. */
785 1.1 christos
786 1.1 christos for (timer_ptr = timer_list.first_timer; timer_ptr != NULL;
787 1.1 christos timer_ptr = timer_ptr->next)
788 1.1 christos {
789 1.1 christos if (timer_ptr->timer_id == id)
790 1.1 christos break;
791 1.1 christos }
792 1.1 christos
793 1.1 christos if (timer_ptr == NULL)
794 1.1 christos return;
795 1.1 christos /* Get rid of the timer in the timer list. */
796 1.1 christos if (timer_ptr == timer_list.first_timer)
797 1.1 christos timer_list.first_timer = timer_ptr->next;
798 1.1 christos else
799 1.1 christos {
800 1.1 christos for (prev_timer = timer_list.first_timer;
801 1.1 christos prev_timer->next != timer_ptr;
802 1.1 christos prev_timer = prev_timer->next)
803 1.1 christos ;
804 1.1 christos prev_timer->next = timer_ptr->next;
805 1.1 christos }
806 1.1 christos delete timer_ptr;
807 1.1 christos
808 1.1 christos gdb_notifier.timeout_valid = 0;
809 1.1 christos }
810 1.1 christos
811 1.1 christos /* Convert a std::chrono duration to a struct timeval. */
812 1.1 christos
813 1.1 christos template<typename Duration>
814 1.1 christos static struct timeval
815 1.1 christos duration_cast_timeval (const Duration &d)
816 1.1 christos {
817 1.1 christos using namespace std::chrono;
818 1.1 christos seconds sec = duration_cast<seconds> (d);
819 1.1 christos microseconds msec = duration_cast<microseconds> (d - sec);
820 1.1 christos
821 1.1 christos struct timeval tv;
822 1.1 christos tv.tv_sec = sec.count ();
823 1.1 christos tv.tv_usec = msec.count ();
824 1.1 christos return tv;
825 1.1 christos }
826 1.1 christos
827 1.1 christos /* Update the timeout for the select() or poll(). Returns true if the
828 1.1 christos timer has already expired, false otherwise. */
829 1.1 christos
830 1.1 christos static int
831 1.1 christos update_wait_timeout (void)
832 1.1 christos {
833 1.1 christos if (timer_list.first_timer != NULL)
834 1.1 christos {
835 1.1 christos using namespace std::chrono;
836 1.1 christos steady_clock::time_point time_now = steady_clock::now ();
837 1.1 christos struct timeval timeout;
838 1.1 christos
839 1.1 christos if (timer_list.first_timer->when < time_now)
840 1.1 christos {
841 1.1 christos /* It expired already. */
842 1.1 christos timeout.tv_sec = 0;
843 1.1 christos timeout.tv_usec = 0;
844 1.1 christos }
845 1.1 christos else
846 1.1 christos {
847 1.1 christos steady_clock::duration d = timer_list.first_timer->when - time_now;
848 1.1 christos timeout = duration_cast_timeval (d);
849 1.1 christos }
850 1.1 christos
851 1.1.1.2 christos /* Update the timeout for select/ poll. */
852 1.1.1.2 christos #ifdef HAVE_POLL
853 1.1 christos if (use_poll)
854 1.1.1.2 christos gdb_notifier.poll_timeout = timeout.tv_sec * 1000;
855 1.1 christos else
856 1.1 christos #endif /* HAVE_POLL */
857 1.1 christos {
858 1.1 christos gdb_notifier.select_timeout.tv_sec = timeout.tv_sec;
859 1.1 christos gdb_notifier.select_timeout.tv_usec = timeout.tv_usec;
860 1.1 christos }
861 1.1 christos gdb_notifier.timeout_valid = 1;
862 1.1 christos
863 1.1 christos if (timer_list.first_timer->when < time_now)
864 1.1 christos return 1;
865 1.1 christos }
866 1.1 christos else
867 1.1 christos gdb_notifier.timeout_valid = 0;
868 1.1 christos
869 1.1 christos return 0;
870 1.1 christos }
871 1.1 christos
872 1.1 christos /* Check whether a timer in the timers queue is ready. If a timer is
873 1.1 christos ready, call its handler and return. Update the timeout for the
874 1.1 christos select() or poll() as well. Return 1 if an event was handled,
875 1.1 christos otherwise returns 0.*/
876 1.1 christos
877 1.1 christos static int
878 1.1 christos poll_timers (void)
879 1.1 christos {
880 1.1 christos if (update_wait_timeout ())
881 1.1 christos {
882 1.1 christos struct gdb_timer *timer_ptr = timer_list.first_timer;
883 1.1 christos timer_handler_func *proc = timer_ptr->proc;
884 1.1 christos gdb_client_data client_data = timer_ptr->client_data;
885 1.1 christos
886 1.1 christos /* Get rid of the timer from the beginning of the list. */
887 1.1 christos timer_list.first_timer = timer_ptr->next;
888 1.1 christos
889 1.1 christos /* Delete the timer before calling the callback, not after, in
890 1.1 christos case the callback itself decides to try deleting the timer
891 1.1 christos too. */
892 1.1 christos delete timer_ptr;
893 1.1 christos
894 1.1 christos /* Call the procedure associated with that timer. */
895 1.1 christos (proc) (client_data);
896 1.1 christos
897 1.1 christos return 1;
898 1.1 christos }
899 1.1 christos
900 return 0;
901 }
902