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