* config/tc-hppa.c (pa_ip): Fix thinkos in recent cleanup
[deliverable/binutils-gdb.git] / gdb / event-loop.c
CommitLineData
b5a0ac70
SS
1/* Event loop machinery for GDB, the GNU debugger.
2 Copyright 1999 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 2 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, write to the Free Software
c5aa993b
JM
19 Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
b5a0ac70 21
b5a0ac70 22#include "defs.h"
9e0b60a8
JM
23#include "top.h"
24#include "event-loop.h"
b5a0ac70 25#ifdef HAVE_POLL
9e0b60a8
JM
26#include <poll.h>
27#else
28#include <sys/types.h>
b5a0ac70
SS
29#endif
30#include <errno.h>
9e0b60a8 31#include <setjmp.h>
b5a0ac70
SS
32
33/* Event queue:
34 - the first event in the queue is the head of the queue.
35 It will be the next to be serviced.
36 - the last event in the queue
37
38 Events can be inserted at the front of the queue or at the end of
39 the queue. Events will be extracted from the queue for processing
40 starting from the head. Therefore, events inserted at the head of
adf40b2e 41 the queue will be processed in a last in first out fashion, while
b5a0ac70
SS
42 those inserted at the tail of the queue will be processed in a first
43 in first out manner. All the fields are NULL if the queue is
44 empty. */
45
46static struct
47 {
48 gdb_event *first_event; /* First pending event */
49 gdb_event *last_event; /* Last pending event */
50 }
51event_queue;
52
53/* Gdb_notifier is just a list of file descriptors gdb is interested in.
54 These are the input file descriptor, and the target file
55 descriptor. We have two flavors of the notifier, one for platforms
56 that have the POLL function, the other for those that don't, and
57 only support SELECT. Each of the elements in the gdb_notifier list is
58 basically a description of what kind of events gdb is interested
59 in, for each fd. */
60
392a587b 61/* As of 1999-04-30 only the input file descriptor is registered with the
b5a0ac70
SS
62 event loop. */
63
64#ifdef HAVE_POLL
65/* Poll based implementation of the notifier. */
66
67static struct
68 {
69 /* Ptr to head of file handler list. */
70 file_handler *first_file_handler;
71
72 /* Ptr to array of pollfd structures. */
73 struct pollfd *poll_fds;
74
75 /* Number of file descriptors to monitor. */
76 int num_fds;
77
78 }
79gdb_notifier;
80
81#else /* ! HAVE_POLL */
82
83/* Select based implementation of the notifier. */
84
85static struct
86 {
87 /* Ptr to head of file handler list. */
88 file_handler *first_file_handler;
89
90 /* Masks to be used in the next call to select.
91 Bits are set in response to calls to create_file_handler. */
92 fd_mask check_masks[3 * MASK_SIZE];
93
94 /* What file descriptors were found ready by select. */
95 fd_mask ready_masks[3 * MASK_SIZE];
96
97 /* Number of valid bits (highest fd value + 1). */
98 int num_fds;
99
100 }
101gdb_notifier;
102
103#endif /* HAVE_POLL */
104
105/* All the async_signal_handlers gdb is interested in are kept onto
106 this list. */
107static struct
108 {
109 /* Pointer to first in handler list. */
c5aa993b
JM
110 async_signal_handler *first_handler;
111
b5a0ac70 112 /* Pointer to last in handler list. */
c5aa993b 113 async_signal_handler *last_handler;
b5a0ac70
SS
114 }
115sighandler_list;
116
117/* Is any of the handlers ready? Check this variable using
118 check_async_ready. This is used by process_event, to determine
119 whether or not to invoke the invoke_async_signal_handler
120 function. */
121static int async_handler_ready = 0;
122
7be570e7 123static void create_file_handler PARAMS ((int, int, handler_func *, gdb_client_data));
b5a0ac70 124static void invoke_async_signal_handler PARAMS ((void));
cff3e48b 125static void handle_file_event PARAMS ((int));
b5a0ac70 126static int gdb_wait_for_event PARAMS ((void));
085dd6e6 127static int gdb_do_one_event PARAMS ((void));
b5a0ac70 128static int check_async_ready PARAMS ((void));
b5a0ac70
SS
129\f
130
131/* Insert an event object into the gdb event queue at
132 the specified position.
133 POSITION can be head or tail, with values TAIL, HEAD.
134 EVENT_PTR points to the event to be inserted into the queue.
135 The caller must allocate memory for the event. It is freed
136 after the event has ben handled.
137 Events in the queue will be processed head to tail, therefore,
138 events inserted at the head of the queue will be processed
139 as last in first out. Event appended at the tail of the queue
140 will be processed first in first out. */
141static void
142async_queue_event (event_ptr, position)
143 gdb_event *event_ptr;
144 queue_position position;
145{
146 if (position == TAIL)
147 {
148 /* The event will become the new last_event. */
149
150 event_ptr->next_event = NULL;
151 if (event_queue.first_event == NULL)
152 event_queue.first_event = event_ptr;
153 else
154 event_queue.last_event->next_event = event_ptr;
155 event_queue.last_event = event_ptr;
156 }
157 else if (position == HEAD)
158 {
159 /* The event becomes the new first_event. */
160
161 event_ptr->next_event = event_queue.first_event;
162 if (event_queue.first_event == NULL)
163 event_queue.last_event = event_ptr;
164 event_queue.first_event = event_ptr;
165 }
166}
167
cff3e48b
JM
168/* Create a file event, to be enqueued in the event queue for
169 processing. The procedure associated to this event is always
170 handle_file_event, which will in turn invoke the one that was
171 associated to FD when it was registered with the event loop. */
172gdb_event *
173create_file_event (fd)
174 int fd;
175{
176 gdb_event *file_event_ptr;
177
178 file_event_ptr = (gdb_event *) xmalloc (sizeof (gdb_event));
179 file_event_ptr->proc = handle_file_event;
180 file_event_ptr->fd = fd;
181 return (file_event_ptr);
182}
183
b5a0ac70
SS
184/* Process one event.
185 The event can be the next one to be serviced in the event queue,
186 or an asynchronous event handler can be invoked in response to
187 the reception of a signal.
188 If an event was processed (either way), 1 is returned otherwise
189 0 is returned.
190 Scan the queue from head to tail, processing therefore the high
191 priority events first, by invoking the associated event handler
192 procedure. */
193static int
194process_event ()
195{
196 gdb_event *event_ptr, *prev_ptr;
197 event_handler_func *proc;
198 int fd;
199
200 /* First let's see if there are any asynchronous event handlers that
201 are ready. These would be the result of invoking any of the
202 signal handlers. */
203
204 if (check_async_ready ())
205 {
206 invoke_async_signal_handler ();
207 return 1;
208 }
209
210 /* Look in the event queue to find an event that is ready
211 to be processed. */
212
213 for (event_ptr = event_queue.first_event; event_ptr != NULL;
214 event_ptr = event_ptr->next_event)
215 {
216 /* Call the handler for the event. */
217
218 proc = event_ptr->proc;
219 fd = event_ptr->fd;
220
221 /* Let's get rid of the event from the event queue. We need to
222 do this now because while processing the event, the proc
223 function could end up calling 'error' and therefore jump out
224 to the caller of this function, gdb_do_one_event. In that
225 case, we would have on the event queue an event wich has been
226 processed, but not deleted. */
227
228 if (event_queue.first_event == event_ptr)
229 {
230 event_queue.first_event = event_ptr->next_event;
231 if (event_ptr->next_event == NULL)
232 event_queue.last_event = NULL;
233 }
234 else
235 {
236 prev_ptr = event_queue.first_event;
237 while (prev_ptr->next_event != event_ptr)
238 prev_ptr = prev_ptr->next_event;
239
240 prev_ptr->next_event = event_ptr->next_event;
241 if (event_ptr->next_event == NULL)
242 event_queue.last_event = prev_ptr;
243 }
244 free ((char *) event_ptr);
245
246 /* Now call the procedure associted with the event. */
247 (*proc) (fd);
248 return 1;
249 }
250
251 /* this is the case if there are no event on the event queue. */
252 return 0;
253}
254
255/* Process one high level event. If nothing is ready at this time,
256 wait for something to happen (via gdb_wait_for_event), then process
257 it. Returns 1 if something was done otherwise returns 0 (this can
258 happen if there are no event sources to wait for). */
085dd6e6 259static int
b5a0ac70
SS
260gdb_do_one_event ()
261{
262 int result = 0;
263
264 while (1)
265 {
266 if (!SET_TOP_LEVEL ())
267 {
268 /* Any events already waiting in the queue? */
269 if (process_event ())
270 {
271 result = 1;
272 break;
273 }
274
275 /* Wait for a new event. If gdb_wait_for_event returns -1,
276 we should get out because this means that there are no
277 event sources left. This will make the event loop stop,
278 and the application exit. */
279
280 result = gdb_wait_for_event ();
281 if (result < 0)
282 {
283 result = 0;
284 break;
285 }
286
287 /* Handle any new events occurred while waiting. */
288 if (process_event ())
289 {
290 result = 1;
291 break;
292 }
293
294 /* If gdb_wait_for_event has returned 1, it means that one
295 event has been handled. We break out of the loop. */
296 if (result)
297 break;
298 } /* end of if !set_top_level */
299 else
300 {
085dd6e6
JM
301 /* FIXME: this should really be a call to a hook that is
302 interface specific, because interfaces can display the
303 prompt in their own way. */
b5a0ac70
SS
304 display_gdb_prompt (0);
305 /* Maybe better to set a flag to be checked somewhere as to
306 whether display the prompt or not. */
307 }
308 }
309 return result;
310}
43ff13b4 311\f
085dd6e6
JM
312
313/* Start up the event loop. This is the entry point to the event loop
314 from the command loop. */
c5aa993b 315void
085dd6e6
JM
316start_event_loop ()
317{
318 /* Loop until there is something to do. This is the entry point to
319 the event loop engine. gdb_do_one_event will process one event
320 for each invocation. It always returns 1, unless there are no
321 more event sources registered. In this case it returns 0. */
322 while (gdb_do_one_event () != 0)
323 ;
324
325 /* We are done with the event loop. There are no more event sources
326 to listen to. So we exit GDB. */
327 return;
328}
b5a0ac70
SS
329\f
330
c5aa993b 331
085dd6e6
JM
332/* Wrapper function for create_file_handler, so that the caller
333 doesn't have to know implementation details about the use of poll
334 vs. select. */
c5aa993b 335void
085dd6e6
JM
336add_file_handler (fd, proc, client_data)
337 int fd;
7be570e7 338 void (*proc) (void);
085dd6e6
JM
339 gdb_client_data client_data;
340{
341#ifdef HAVE_POLL
7be570e7 342 create_file_handler (fd, POLLIN, (handler_func *) proc, client_data);
085dd6e6 343#else
7be570e7 344 create_file_handler (fd, GDB_READABLE, (handler_func *) proc, client_data);
085dd6e6
JM
345#endif
346}
347
b5a0ac70
SS
348/* Add a file handler/descriptor to the list of descriptors we are
349 interested in.
350 FD is the file descriptor for the file/stream to be listened to.
351 For the poll case, MASK is a combination (OR) of
352 POLLIN, POLLRDNORM, POLLRDBAND, POLLPRI, POLLOUT, POLLWRNORM,
353 POLLWRBAND: these are the events we are interested in. If any of them
354 occurs, proc should be called.
355 For the select case, MASK is a combination of READABLE, WRITABLE, EXCEPTION.
356 PROC is the procedure that will be called when an event occurs for
357 FD. CLIENT_DATA is the argument to pass to PROC. */
085dd6e6 358static void
b5a0ac70
SS
359create_file_handler (fd, mask, proc, client_data)
360 int fd;
361 int mask;
7be570e7 362 handler_func *proc;
b5a0ac70
SS
363 gdb_client_data client_data;
364{
365 file_handler *file_ptr;
366
367#ifndef HAVE_POLL
368 int index, bit;
369#endif
370
371 /* Do we already have a file handler for this file? (We may be
372 changing its associated procedure). */
373 for (file_ptr = gdb_notifier.first_file_handler; file_ptr != NULL;
374 file_ptr = file_ptr->next_file)
375 {
376 if (file_ptr->fd == fd)
377 break;
378 }
379
380 /* It is a new file descriptor. */
381 if (file_ptr == NULL)
382 {
383 file_ptr = (file_handler *) xmalloc (sizeof (file_handler));
384 file_ptr->fd = fd;
385 file_ptr->ready_mask = 0;
386 file_ptr->next_file = gdb_notifier.first_file_handler;
387 gdb_notifier.first_file_handler = file_ptr;
388 }
389 file_ptr->proc = proc;
390 file_ptr->client_data = client_data;
391 file_ptr->mask = mask;
392
393#ifdef HAVE_POLL
394
395 gdb_notifier.num_fds++;
9e0b60a8
JM
396 if (gdb_notifier.poll_fds)
397 gdb_notifier.poll_fds =
398 (struct pollfd *) realloc (gdb_notifier.poll_fds,
c5aa993b 399 (gdb_notifier.num_fds) * sizeof (struct pollfd));
9e0b60a8 400 else
c5aa993b
JM
401 gdb_notifier.poll_fds =
402 (struct pollfd *) xmalloc (sizeof (struct pollfd));
b5a0ac70
SS
403 (gdb_notifier.poll_fds + gdb_notifier.num_fds - 1)->fd = fd;
404 (gdb_notifier.poll_fds + gdb_notifier.num_fds - 1)->events = mask;
405 (gdb_notifier.poll_fds + gdb_notifier.num_fds - 1)->revents = 0;
406
407#else /* ! HAVE_POLL */
408
409 index = fd / (NBBY * sizeof (fd_mask));
410 bit = 1 << (fd % (NBBY * sizeof (fd_mask)));
411
412 if (mask & GDB_READABLE)
413 gdb_notifier.check_masks[index] |= bit;
414 else
415 gdb_notifier.check_masks[index] &= ~bit;
416
417 if (mask & GDB_WRITABLE)
418 (gdb_notifier.check_masks + MASK_SIZE)[index] |= bit;
419 else
420 (gdb_notifier.check_masks + MASK_SIZE)[index] &= ~bit;
421
422 if (mask & GDB_EXCEPTION)
423 (gdb_notifier.check_masks + 2 * (MASK_SIZE))[index] |= bit;
424 else
425 (gdb_notifier.check_masks + 2 * (MASK_SIZE))[index] &= ~bit;
426
427 if (gdb_notifier.num_fds <= fd)
428 gdb_notifier.num_fds = fd + 1;
429
430#endif /* HAVE_POLL */
431}
432
433/* Remove the file descriptor FD from the list of monitored fd's:
434 i.e. we don't care anymore about events on the FD. */
435void
436delete_file_handler (fd)
437 int fd;
438{
439 file_handler *file_ptr, *prev_ptr = NULL;
440 int i, j;
441 struct pollfd *new_poll_fds;
442#ifndef HAVE_POLL
443 int index, bit;
444 unsigned long flags;
445#endif
446
447 /* Find the entry for the given file. */
448
449 for (file_ptr = gdb_notifier.first_file_handler; file_ptr != NULL;
450 file_ptr = file_ptr->next_file)
451 {
452 if (file_ptr->fd == fd)
453 break;
454 }
455
456 if (file_ptr == NULL)
457 return;
458
b5a0ac70
SS
459#ifdef HAVE_POLL
460 /* Create a new poll_fds array by copying every fd's information but the
461 one we want to get rid of. */
462
463 new_poll_fds =
464 (struct pollfd *) xmalloc ((gdb_notifier.num_fds - 1) * sizeof (struct pollfd));
465
466 for (i = 0, j = 0; i < gdb_notifier.num_fds; i++)
467 {
468 if ((gdb_notifier.poll_fds + i)->fd != fd)
469 {
470 (new_poll_fds + j)->fd = (gdb_notifier.poll_fds + i)->fd;
471 (new_poll_fds + j)->events = (gdb_notifier.poll_fds + i)->events;
472 (new_poll_fds + j)->revents = (gdb_notifier.poll_fds + i)->revents;
473 j++;
474 }
475 }
476 free (gdb_notifier.poll_fds);
477 gdb_notifier.poll_fds = new_poll_fds;
478 gdb_notifier.num_fds--;
479
480#else /* ! HAVE_POLL */
481
482 index = fd / (NBBY * sizeof (fd_mask));
483 bit = 1 << (fd % (NBBY * sizeof (fd_mask)));
484
485 if (file_ptr->mask & GDB_READABLE)
486 gdb_notifier.check_masks[index] &= ~bit;
487 if (file_ptr->mask & GDB_WRITABLE)
488 (gdb_notifier.check_masks + MASK_SIZE)[index] &= ~bit;
489 if (file_ptr->mask & GDB_EXCEPTION)
490 (gdb_notifier.check_masks + 2 * (MASK_SIZE))[index] &= ~bit;
491
492 /* Find current max fd. */
493
494 if ((fd + 1) == gdb_notifier.num_fds)
495 {
496 for (gdb_notifier.num_fds = 0; index >= 0; index--)
497 {
498 flags = gdb_notifier.check_masks[index]
499 | (gdb_notifier.check_masks + MASK_SIZE)[index]
500 | (gdb_notifier.check_masks + 2 * (MASK_SIZE))[index];
501 if (flags)
502 {
503 for (i = (NBBY * sizeof (fd_mask)); i > 0; i--)
504 {
505 if (flags & (((unsigned long) 1) << (i - 1)))
506 break;
507 }
508 gdb_notifier.num_fds = index * (NBBY * sizeof (fd_mask)) + i;
509 break;
510 }
511 }
512 }
513#endif /* HAVE_POLL */
514
cff3e48b
JM
515 /* Deactivate the file descriptor, by clearing its mask,
516 so that it will not fire again. */
517
518 file_ptr->mask = 0;
519
b5a0ac70
SS
520 /* Get rid of the file handler in the file handler list. */
521 if (file_ptr == gdb_notifier.first_file_handler)
522 gdb_notifier.first_file_handler = file_ptr->next_file;
523 else
524 {
525 for (prev_ptr = gdb_notifier.first_file_handler;
9e0b60a8 526 prev_ptr->next_file != file_ptr;
b5a0ac70
SS
527 prev_ptr = prev_ptr->next_file)
528 ;
529 prev_ptr->next_file = file_ptr->next_file;
530 }
531 free ((char *) file_ptr);
532}
533
534/* Handle the given event by calling the procedure associated to the
535 corresponding file handler. Called by process_event indirectly,
536 through event_ptr->proc. EVENT_FILE_DESC is file descriptor of the
537 event in the front of the event queue. */
538static void
539handle_file_event (event_file_desc)
540 int event_file_desc;
541{
542 file_handler *file_ptr;
543 int mask, error_mask;
544
545 /* Search the file handler list to find one that matches the fd in
546 the event. */
547 for (file_ptr = gdb_notifier.first_file_handler; file_ptr != NULL;
548 file_ptr = file_ptr->next_file)
549 {
550 if (file_ptr->fd == event_file_desc)
551 {
552 /* With poll, the ready_mask could have any of three events
553 set to 1: POLLHUP, POLLERR, POLLNVAL. These events cannot
554 be used in the requested event mask (events), but they
555 can be returned in the return mask (revents). We need to
556 check for those event too, and add them to the mask which
557 will be passed to the handler. */
558
559 /* See if the desired events (mask) match the received
560 events (ready_mask). */
561
562#ifdef HAVE_POLL
563 error_mask = POLLHUP | POLLERR | POLLNVAL;
564 mask = (file_ptr->ready_mask & file_ptr->mask) |
565 (file_ptr->ready_mask & error_mask);
566
567#else /* ! HAVE_POLL */
568 mask = file_ptr->ready_mask & file_ptr->mask;
569#endif /* HAVE_POLL */
570
571 /* Clear the received events for next time around. */
572 file_ptr->ready_mask = 0;
573
574 /* If there was a match, then call the handler. */
575 if (mask != 0)
7be570e7 576 (*file_ptr->proc) (file_ptr->client_data);
b5a0ac70
SS
577 break;
578 }
579 }
580}
581
582/* Called by gdb_do_one_event to wait for new events on the
583 monitored file descriptors. Queue file events as they are
584 detected by the poll.
585 If there are no events, this function will block in the
586 call to poll.
587 Return -1 if there are no files descriptors to monitor,
588 otherwise return 0. */
589static int
590gdb_wait_for_event ()
591{
592 file_handler *file_ptr;
593 gdb_event *file_event_ptr;
0f71a2f6
JM
594 int num_found = 0;
595 int i;
b5a0ac70
SS
596
597#ifndef HAVE_POLL
598 int mask, bit, index;
599#endif
600
7be570e7
JM
601 /* Make sure all output is done before getting another event. */
602 gdb_flush (gdb_stdout);
603 gdb_flush (gdb_stderr);
604
b5a0ac70
SS
605 if (gdb_notifier.num_fds == 0)
606 return -1;
607
608#ifdef HAVE_POLL
609 num_found =
610 poll (gdb_notifier.poll_fds, (unsigned long) gdb_notifier.num_fds, -1);
611
612#else /* ! HAVE_POLL */
613 memcpy (gdb_notifier.ready_masks,
614 gdb_notifier.check_masks,
615 3 * MASK_SIZE * sizeof (fd_mask));
616 num_found = select (gdb_notifier.num_fds,
617 (SELECT_MASK *) & gdb_notifier.ready_masks[0],
618 (SELECT_MASK *) & gdb_notifier.ready_masks[MASK_SIZE],
619 (SELECT_MASK *) & gdb_notifier.ready_masks[2 * MASK_SIZE],
620 NULL);
621
622 /* Clear the masks after an error from select. */
623 if (num_found == -1)
624 memset (gdb_notifier.ready_masks,
625 0, 3 * MASK_SIZE * sizeof (fd_mask));
626
627#endif /* HAVE_POLL */
628
629 /* Enqueue all detected file events. */
630
631#ifdef HAVE_POLL
632
633 for (i = 0; (i < gdb_notifier.num_fds) && (num_found > 0); i++)
634 {
635 if ((gdb_notifier.poll_fds + i)->revents)
636 num_found--;
637 else
638 continue;
639
640 for (file_ptr = gdb_notifier.first_file_handler;
641 file_ptr != NULL;
642 file_ptr = file_ptr->next_file)
643 {
644 if (file_ptr->fd == (gdb_notifier.poll_fds + i)->fd)
645 break;
646 }
647
648 if (file_ptr)
649 {
650 /* Enqueue an event only if this is still a new event for
651 this fd. */
652 if (file_ptr->ready_mask == 0)
653 {
cff3e48b 654 file_event_ptr = create_file_event (file_ptr->fd);
b5a0ac70
SS
655 async_queue_event (file_event_ptr, TAIL);
656 }
657 }
658
659 file_ptr->ready_mask = (gdb_notifier.poll_fds + i)->revents;
660 }
661
662#else /* ! HAVE_POLL */
663 for (file_ptr = gdb_notifier.first_file_handler;
664 (file_ptr != NULL) && (num_found > 0);
665 file_ptr = file_ptr->next_file)
666 {
667 index = file_ptr->fd / (NBBY * sizeof (fd_mask));
668 bit = 1 << (file_ptr->fd % (NBBY * sizeof (fd_mask)));
669 mask = 0;
670
671 if (gdb_notifier.ready_masks[index] & bit)
672 mask |= GDB_READABLE;
673 if ((gdb_notifier.ready_masks + MASK_SIZE)[index] & bit)
674 mask |= GDB_WRITABLE;
675 if ((gdb_notifier.ready_masks + 2 * (MASK_SIZE))[index] & bit)
676 mask |= GDB_EXCEPTION;
677
678 if (!mask)
679 continue;
680 else
681 num_found--;
682
683 /* Enqueue an event only if this is still a new event for
684 this fd. */
685
686 if (file_ptr->ready_mask == 0)
687 {
cff3e48b 688 file_event_ptr = create_file_event (file_ptr->fd);
b5a0ac70
SS
689 async_queue_event (file_event_ptr, TAIL);
690 }
691 file_ptr->ready_mask = mask;
692 }
693#endif /* HAVE_POLL */
694
695 return 0;
696}
697\f
698
699/* Create an asynchronous handler, allocating memory for it.
700 Return a pointer to the newly created handler.
701 This pointer will be used to invoke the handler by
702 invoke_async_signal_handler.
703 PROC is the function to call with CLIENT_DATA argument
704 whenever the handler is invoked. */
705async_signal_handler *
706create_async_signal_handler (proc, client_data)
7be570e7 707 handler_func *proc;
b5a0ac70
SS
708 gdb_client_data client_data;
709{
710 async_signal_handler *async_handler_ptr;
711
712 async_handler_ptr =
713 (async_signal_handler *) xmalloc (sizeof (async_signal_handler));
714 async_handler_ptr->ready = 0;
715 async_handler_ptr->next_handler = NULL;
716 async_handler_ptr->proc = proc;
717 async_handler_ptr->client_data = client_data;
718 if (sighandler_list.first_handler == NULL)
719 sighandler_list.first_handler = async_handler_ptr;
720 else
721 sighandler_list.last_handler->next_handler = async_handler_ptr;
722 sighandler_list.last_handler = async_handler_ptr;
723 return async_handler_ptr;
724}
725
726/* Mark the handler (ASYNC_HANDLER_PTR) as ready. This information will
727 be used when the handlers are invoked, after we have waited for
728 some event. The caller of this function is the interrupt handler
729 associated with a signal. */
730void
731mark_async_signal_handler (async_handler_ptr)
732 async_signal_handler *async_handler_ptr;
733{
734 ((async_signal_handler *) async_handler_ptr)->ready = 1;
735 async_handler_ready = 1;
736}
737
738/* Call all the handlers that are ready. */
739static void
740invoke_async_signal_handler ()
741{
742 async_signal_handler *async_handler_ptr;
743
744 if (async_handler_ready == 0)
745 return;
746 async_handler_ready = 0;
747
748 /* Invoke ready handlers. */
749
750 while (1)
751 {
c5aa993b 752 for (async_handler_ptr = sighandler_list.first_handler;
b5a0ac70
SS
753 async_handler_ptr != NULL;
754 async_handler_ptr = async_handler_ptr->next_handler)
755 {
756 if (async_handler_ptr->ready)
757 break;
758 }
759 if (async_handler_ptr == NULL)
760 break;
761 async_handler_ptr->ready = 0;
762 (*async_handler_ptr->proc) (async_handler_ptr->client_data);
763 }
764
765 return;
766}
767
768/* Delete an asynchronous handler (ASYNC_HANDLER_PTR).
769 Free the space allocated for it. */
770void
771delete_async_signal_handler (async_handler_ptr)
43ff13b4 772 async_signal_handler **async_handler_ptr;
b5a0ac70
SS
773{
774 async_signal_handler *prev_ptr;
775
43ff13b4 776 if (sighandler_list.first_handler == (*async_handler_ptr))
b5a0ac70 777 {
43ff13b4 778 sighandler_list.first_handler = (*async_handler_ptr)->next_handler;
b5a0ac70
SS
779 if (sighandler_list.first_handler == NULL)
780 sighandler_list.last_handler = NULL;
781 }
782 else
783 {
784 prev_ptr = sighandler_list.first_handler;
43ff13b4 785 while (prev_ptr->next_handler != (*async_handler_ptr) && prev_ptr)
b5a0ac70 786 prev_ptr = prev_ptr->next_handler;
43ff13b4
JM
787 prev_ptr->next_handler = (*async_handler_ptr)->next_handler;
788 if (sighandler_list.last_handler == (*async_handler_ptr))
b5a0ac70
SS
789 sighandler_list.last_handler = prev_ptr;
790 }
43ff13b4
JM
791 free ((char *) (*async_handler_ptr));
792 (*async_handler_ptr) = NULL;
b5a0ac70
SS
793}
794
795/* Is it necessary to call invoke_async_signal_handler? */
796static int
797check_async_ready ()
798{
799 return async_handler_ready;
800}
This page took 0.062936 seconds and 4 git commands to generate.