int gdb_do_one_event (void) { static int event_source_head = 0; const int number_of_sources = 3; int current = 0; /* First let's see if there are any asynchronous signal handlers that are ready. These would be the result of invoking any of the signal handlers. */ if (invoke_async_signal_handlers ()) return 1; /* To level the fairness across event sources, we poll them in a round-robin fashion. */ for (current = 0; current < number_of_sources; current++) { int res; switch (event_source_head) { case 0: /* Are any timers that are ready? */ res = poll_timers (); break; case 1: /* Are there events already waiting to be collected on the monitored file descriptors? */ res = gdb_wait_for_event (0); break; case 2: /* Are there any asynchronous event handlers ready? */ res = check_async_event_handlers (); break; default: internal_error (__FILE__, __LINE__, "unexpected event_source_head %d", event_source_head); } event_source_head++; if (event_source_head == number_of_sources) event_source_head = 0; if (res > 0) return 1; } /* Block waiting for a new event. If gdb_wait_for_event returns -1, we should get out because this means that there are no event sources left. This will make the event loop stop, and the application exit. */ if (gdb_wait_for_event (1) < 0) return -1; /* If gdb_wait_for_event has returned 1, it means that one event has been handled. We break out of the loop. */ return 1; }
/* Process one event. The event can be the next one to be serviced in the event queue, or an asynchronous event handler can be invoked in response to the reception of a signal. If an event was processed (either way), 1 is returned otherwise 0 is returned. Scan the queue from head to tail, processing therefore the high priority events first, by invoking the associated event handler procedure. */ static int process_event (void) { gdb_event *event_ptr, *prev_ptr; event_handler_func *proc; event_data data; /* First let's see if there are any asynchronous event handlers that are ready. These would be the result of invoking any of the signal handlers. */ if (invoke_async_signal_handlers ()) return 1; /* Look in the event queue to find an event that is ready to be processed. */ for (event_ptr = event_queue.first_event; event_ptr != NULL; event_ptr = event_ptr->next_event) { /* Call the handler for the event. */ proc = event_ptr->proc; data = event_ptr->data; /* Let's get rid of the event from the event queue. We need to do this now because while processing the event, the proc function could end up calling 'error' and therefore jump out to the caller of this function, gdb_do_one_event. In that case, we would have on the event queue an event wich has been processed, but not deleted. */ if (event_queue.first_event == event_ptr) { event_queue.first_event = event_ptr->next_event; if (event_ptr->next_event == NULL) event_queue.last_event = NULL; } else { prev_ptr = event_queue.first_event; while (prev_ptr->next_event != event_ptr) prev_ptr = prev_ptr->next_event; prev_ptr->next_event = event_ptr->next_event; if (event_ptr->next_event == NULL) event_queue.last_event = prev_ptr; } xfree (event_ptr); /* Now call the procedure associated with the event. */ (*proc) (data); return 1; } /* this is the case if there are no event on the event queue. */ return 0; }