This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


On 01/25/2013 03:08 AM, Pedro Alves wrote:
>> -  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
>> >      {
> Any reason not to do the exact same the gdbserver patch did? :
> 

No.  This patch is for refactor, so I don't consider the consistency
between GDB and GDBserver.

>     if (!QUEUE_is_empty (gdb_event_p, event_queue))
> 
> and then leave the return bit alone at the bottom.
> 
>> >--- 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 ();
>> >+
> Looks like this needs to be before scripts too, as those can
> run execution commands too.  I think it's just best to put
> this in gdb_init, close to other "manual" initialize_foo calls.
> 

Add a function "initialized_event_loop" and call it in gdb_init.  The
patch below is tested on x86_64-linux.  Is it OK?

-- 
Yao (éå)

gdb:

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

	* event-loop.c: Include "queue.h".
	(gdb_event_p): New typedef.
	(DECLARE_QUEUE_P): Use.
	(DEFINE_QUEUE_P): Use.
	(async_queue_event): Remove.
	(gdb_event_xfree): New.
	(initialize_event_loop): New.
	(process_event): Use QUEUE macros.
	(event_queue): Remove.
	(gdb_wait_for_event): Caller update.
	(check_async_event_handlers): Likewise.
	(poll_timers): Likewise.
	* event-loop.h (initialize_event_loop): Declare.
	* event-loop.c (gdb_event_xfree): New.
	* top.c (gdb_init): Call initialize_event_loop.
---
 gdb/event-loop.c |  121 +++++++++++++++++-------------------------------------
 gdb/event-loop.h |    1 +
 gdb/top.c        |    1 +
 3 files changed, 40 insertions(+), 83 deletions(-)

diff --git a/gdb/event-loop.c b/gdb/event-loop.c
index aea3b5e..f34f153 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);
 
 
-/* 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.  */
@@ -324,6 +284,23 @@ create_file_event (int fd)
   return create_event (handle_file_event, data);
 }
 
+
+/* Free EVENT.  */
+
+static void
+gdb_event_xfree (struct gdb_event *event)
+{
+  xfree (event);
+}
+
+/* Initialize the event queue.  */
+
+void
+initialize_event_loop (void)
+{
+  event_queue = QUEUE_alloc (gdb_event_p, gdb_event_xfree);
+}
+
 /* 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
@@ -336,10 +313,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,38 +323,20 @@ 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))
     {
-      /* 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);
+      gdb_event_xfree (event_ptr);
 
       /* Now call the procedure associated with the event.  */
       (*proc) (data);
@@ -922,7 +877,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 +913,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 +1099,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 +1306,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..e994fc1 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 initialize_event_loop (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/top.c b/gdb/top.c
index e9d6c1c..e9a40fc 100644
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -1713,6 +1713,7 @@ gdb_init (char *argv0)
   initialize_inferiors ();
   initialize_current_architecture ();
   init_cli_cmds();
+  initialize_event_loop ();
   init_main ();			/* But that omits this file!  Do it now.  */
 
   initialize_stdin_serial ();
-- 
1.7.7.6


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]