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