[PATCH 3/3] gdb: replace event_queue with QUEUE

Yao Qi
2013-01-24T01:15:10Z

Hi,
This patch rewrites 'event_queue' with QUEUE API in common/queue.h.
This patch is a little different from the GDBserver one, because the
event queue is used before the event loop is started. So I add a new
function init_event_queue to initialize event queue earlier.

Regression tested on x86_64-linux with board file {unix,
native-gdbserver} x {sync, async}.

gdb:

2013-01-24 Yao Qi <yao@codesourcery.com>

* event-loop.c: Include "queue.h".
(gdb_event_p): New typedef.
(typedef struct async_event_handler):
(DECLARE_QUEUE_P): Use.
(DEFINE_QUEUE_P): Use.
(async_queue_event): Remove.
(static int gdb_wait_for_event):
(process_event): Use QUEUE macros.
(event_queue): Remove.
(gdb_wait_for_event): Caller update.
(check_async_event_handlers): Likewise.
(poll_timers): Likewise.
(gdb_event_xfree): New.
(init_event_queue): New.
* event-loop.h: Declare it.
* main.c (captured_main): Call init_event_queue.
---
gdb/event-loop.c | 122 ++++++++++++++++-------------------------------------
gdb/event-loop.h | 1 +
gdb/main.c | 4 ++
3 files changed, 42 insertions(+), 85 deletions(-)

diff --git a/gdb/event-loop.c b/gdb/event-loop.c
index aea3b5e..05a4598 100644
--- a/gdb/event-loop.c
+++ b/gdb/event-loop.c
@@ -20,6 +20,7 @@
#include "defs.h"
#include "event-loop.h"
#include "event-top.h"
+#include "queue.h"

#ifdef HAVE_POLL
#if defined (HAVE_POLL_H)
@@ -68,17 +69,14 @@ typedef void (event_handler_func) (event_data);
case of async signal handlers, it is
invoke_async_signal_handler. */

-struct gdb_event
+typedef struct gdb_event
{
/* Procedure to call to service this event. */
event_handler_func *proc;

/* Data to pass to the event handler. */
event_data data;
-
- /* Next in list of events or NULL. */
- struct gdb_event *next_event;
- };
+ } *gdb_event_p;

/* Information about each file descriptor we register with the event
loop. */
@@ -140,26 +138,9 @@ typedef struct async_event_handler
}
async_event_handler;

-
-/* Event queue:
- - the first event in the queue is the head of the queue.
- It will be the next to be serviced.
- - the last event in the queue
-
- Events can be inserted at the front of the queue or at the end of
- the queue. Events will be extracted from the queue for processing
- starting from the head. Therefore, events inserted at the head of
- the queue will be processed in a last in first out fashion, while
- those inserted at the tail of the queue will be processed in a first
- in first out manner. All the fields are NULL if the queue is
- empty. */
-
-static struct
- {
- gdb_event *first_event; /* First pending event. */
- gdb_event *last_event; /* Last pending event. */
- }
-event_queue;
+DECLARE_QUEUE_P (gdb_event_p);
+DEFINE_QUEUE_P (gdb_event_p);
+static QUEUE(gdb_event_p) *event_queue = NULL;

/* Gdb_notifier is just a list of file descriptors gdb is interested in.
These are the input file descriptor, and the target file
@@ -274,27 +255,6 @@ static int gdb_wait_for_event (int);
static void poll_timers (void);
\f

-/* Insert an event object into the gdb event queue.
- EVENT_PTR points to the event to be inserted into the queue.
- The caller must allocate memory for the event. It is freed
- after the event has ben handled.
- Events in the queue will be processed head to tail, therefore,
- events inserted at the head of the queue will be processed
- as last in first out. Event appended at the tail of the queue
- will be processed first in first out. */
-static void
-async_queue_event (gdb_event * event_ptr)
-{
- /* The event will become the new last_event. */
-
- event_ptr->next_event = NULL;
- if (event_queue.first_event == NULL)
- event_queue.first_event = event_ptr;
- else
- event_queue.last_event->next_event = event_ptr;
- event_queue.last_event = event_ptr;
-}
-
/* Create a generic event, to be enqueued in the event queue for
processing. PROC is the procedure associated to the event. DATA
is passed to PROC upon PROC invocation. */
@@ -336,10 +296,6 @@ create_file_event (int fd)
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. */
@@ -350,46 +306,28 @@ process_event (void)
/* 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)
+ if (QUEUE_is_empty (gdb_event_p, event_queue))
+ /* This is the case if there are no event on the event queue. */
+ return 0;
+ else
{
- /* 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;
+ 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. */
+ gdb_event *event_ptr = QUEUE_deque (gdb_event_p, event_queue);
+ /* Call the handler for the event. */
+ event_handler_func *proc = event_ptr->proc;
+ event_data data = event_ptr->data;

- 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;
}

/* Process one high level event. If nothing is ready at this time,
@@ -456,6 +394,20 @@ gdb_do_one_event (void)
return 1;
}

+/* Free EVENT. */
+
+static void
+gdb_event_xfree (struct gdb_event *event)
+{
+ xfree (event);
+}
+
+void
+init_event_queue (void)
+{
+ event_queue = QUEUE_alloc (gdb_event_p, gdb_event_xfree);
+}
+
/* Start up the event loop. This is the entry point to the event loop
from the command loop. */

@@ -922,7 +874,7 @@ gdb_wait_for_event (int block)
if (file_ptr->ready_mask == 0)
{
file_event_ptr = create_file_event (file_ptr->fd);
- async_queue_event (file_event_ptr);
+ QUEUE_enque (gdb_event_p, event_queue, file_event_ptr);
}
file_ptr->ready_mask = (gdb_notifier.poll_fds + i)->revents;
}
@@ -958,7 +910,7 @@ gdb_wait_for_event (int block)
if (file_ptr->ready_mask == 0)
{
file_event_ptr = create_file_event (file_ptr->fd);
- async_queue_event (file_event_ptr);
+ QUEUE_enque (gdb_event_p, event_queue, file_event_ptr);
}
file_ptr->ready_mask = mask;
}
@@ -1144,7 +1096,7 @@ check_async_event_handlers (void)
data.ptr = hdata;

event_ptr = create_event (invoke_async_event_handler, data);
- async_queue_event (event_ptr);
+ QUEUE_enque (gdb_event_p, event_queue, event_ptr);
}
}
}
@@ -1351,7 +1303,7 @@ poll_timers (void)
event_ptr = (gdb_event *) xmalloc (sizeof (gdb_event));
event_ptr->proc = handle_timer_event;
event_ptr->data.integer = timer_list.first_timer->timer_id;
- async_queue_event (event_ptr);
+ QUEUE_enque (gdb_event_p, event_queue, event_ptr);
}

/* Now we need to update the timeout for select/ poll, because
diff --git a/gdb/event-loop.h b/gdb/event-loop.h
index fc95cf1..fd7efc0 100644
--- a/gdb/event-loop.h
+++ b/gdb/event-loop.h
@@ -77,6 +77,7 @@ typedef void (timer_handler_func) (gdb_client_data);

/* Exported functions from event-loop.c */

+extern void init_event_queue (void);
extern void start_event_loop (void);
extern int gdb_do_one_event (void);
extern void delete_file_handler (int fd);
diff --git a/gdb/main.c b/gdb/main.c
index 6ed014f..689b2d8 100644
--- a/gdb/main.c
+++ b/gdb/main.c
@@ -997,6 +997,10 @@ captured_main (void *data)
ALL_OBJFILES (objfile)
load_auto_scripts_for_objfile (objfile);

+ /* Initialize event queue here because execution commands below
+ will push events to the queue. */
+ init_event_queue ();
+
/* Process '-x' and '-ex' options. */
for (i = 0; VEC_iterate (cmdarg_s, cmdarg_vec, i, cmdarg_p); i++)
switch (cmdarg_p->type)
--
1.7.7.6