Simplify event-loop core, remove two-step event processing
Even with the previous patch installed, we'll still see
sigall-reverse.exp occasionally fail. The problem is that the event
loop's event handling processing is done in two steps:
#1 - poll all event sources, and push new event objects to the event
queue, until all event sources are drained.
#2 - go through the event queue, processing each event object at a
time. For each event, call the associated callback, and deletes the
event object from the queue.
and then bad things happen if between #1 and #2 something decides that
events from an event source that has already queued events shouldn't
be processed yet. To do that, we either remove the event source from
the list of event sources, or clear its "have events" flag. However,
if an event for that source has meanwhile already been pushed in the
event queue, #2 will still process it and call the associated
callback...
One way to fix it that I considered was to do something to the event
objects already in the event queue when an event source is no longer
interesting. But then I couldn't find any good reason for the
two-step process in the first place. It's much simpler (and less
code) to call the event source callbacks as we poll the sources and
find events.
Tested on x86-64 Fedora 20, native and gdbserver.
gdb/
2015-02-03 Pedro Alves <palves@redhat.com>
* event-loop.c: Don't declare nor define a queue type for
gdb_event_p.
(event_queue): Delete.
(create_event, create_file_event, gdb_event_xfree)
(initialize_event_loop, process_event): Delete.
(gdb_do_one_event): Return as soon as one event is handled.
(handle_file_event): Change prototype. Used the passed in
file_handler pointer and ready_mask instead of looping over all
file handlers.
(gdb_wait_for_event): Update the poll/select timeouts before
blocking. Run event handlers directly instead of queueing events.
Return as soon as one event is handled.
(struct async_event_handler_data): Delete.
(invoke_async_event_handler): Delete.
(check_async_event_handlers): Change return type to int. Run
event handlers directly instead of queueing events. Return as
soon as one event is handled.
(handle_timer_event): Delete.
(update_wait_timeout): New function, factored out from
poll_timers.
(poll_timers): Reimplement.
* event-loop.h (initialize_event_loop): Delete declaration.
* top.c (gdb_init): Don't call initialize_event_loop.