Automatic date update in version.in
[platform/upstream/binutils.git] / gdb / event-loop.c
index b6702f8..023310c 100644 (file)
@@ -1,6 +1,5 @@
 /* Event loop machinery for GDB, the GNU debugger.
-   Copyright (C) 1999, 2000, 2001, 2002, 2005, 2006, 2007, 2008, 2009, 2010,
-   2011 Free Software Foundation, Inc.
+   Copyright (C) 1999-2014 Free Software Foundation, Inc.
    Written by Elena Zannoni <ezannoni@cygnus.com> of Cygnus Solutions.
 
    This file is part of GDB.
@@ -21,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)
 #endif
 
 #include <sys/types.h>
-#include "gdb_string.h"
-#include <errno.h>
 #include <sys/time.h>
-#include "exceptions.h"
-#include "gdb_assert.h"
 #include "gdb_select.h"
+#include "observer.h"
 
 /* Tell create_file_handler what events we are interested in.
    This is used by the select version of the event loop.  */
@@ -69,17 +66,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.  */
@@ -141,26 +135,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
@@ -275,41 +252,6 @@ static int gdb_wait_for_event (int);
 static void poll_timers (void);
 \f
 
-/* Insert an event object into the gdb event queue at 
-   the specified position.
-   POSITION can be head or tail, with values TAIL, HEAD.
-   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, queue_position position)
-{
-  if (position == TAIL)
-    {
-      /* 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;
-    }
-  else if (position == HEAD)
-    {
-      /* The event becomes the new first_event.  */
-
-      event_ptr->next_event = event_queue.first_event;
-      if (event_queue.first_event == NULL)
-       event_queue.last_event = event_ptr;
-      event_queue.first_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.  */
@@ -339,6 +281,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
@@ -351,10 +310,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.  */
@@ -365,38 +320,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);
@@ -410,11 +347,10 @@ process_event (void)
 /* Process one high level event.  If nothing is ready at this time,
    wait for something to happen (via gdb_wait_for_event), then process
    it.  Returns >0 if something was done otherwise returns <0 (this
-   can happen if there are no event sources to wait for).  If an error
-   occurs catch_errors() which calls this function returns zero.  */
+   can happen if there are no event sources to wait for).  */
 
 int
-gdb_do_one_event (void *data)
+gdb_do_one_event (void)
 {
   static int event_source_head = 0;
   const int number_of_sources = 3;
@@ -478,34 +414,31 @@ gdb_do_one_event (void *data)
 void
 start_event_loop (void)
 {
-  /* Loop until there is nothing to do.  This is the entry point to the
-     event loop engine.  gdb_do_one_event, called via catch_errors()
-     will process one event for each invocation.  It blocks waits for
-     an event and then processes it.  >0 when an event is processed, 0
-     when catch_errors() caught an error and <0 when there are no
-     longer any event sources registered.  */
+  /* Loop until there is nothing to do.  This is the entry point to
+     the event loop engine.  gdb_do_one_event will process one event
+     for each invocation.  It blocks waiting for an event and then
+     processes it.  */
   while (1)
     {
-      int gdb_result;
-
-      gdb_result = catch_errors (gdb_do_one_event, 0, "", RETURN_MASK_ALL);
-      if (gdb_result < 0)
-       break;
-
-      /* If we long-jumped out of do_one_event, we probably
-         didn't get around to resetting the prompt, which leaves
-         readline in a messed-up state.  Reset it here.  */
+      volatile struct gdb_exception ex;
+      int result = 0;
 
-      if (gdb_result == 0)
+      TRY_CATCH (ex, RETURN_MASK_ALL)
+       {
+         result = gdb_do_one_event ();
+       }
+      if (ex.reason < 0)
        {
+         exception_print (gdb_stderr, ex);
+
          /* If any exception escaped to here, we better enable
             stdin.  Otherwise, any command that calls async_disable_stdin,
             and then throws, will leave stdin inoperable.  */
          async_enable_stdin ();
-         /* FIXME: this should really be a call to a hook that is
-            interface specific, because interfaces can display the
-            prompt in their own way.  */
-         display_gdb_prompt (0);
+         /* If we long-jumped out of do_one_event, we probably didn't
+            get around to resetting the prompt, which leaves readline
+            in a messed-up state.  Reset it here.  */
+         observer_notify_command_error ();
          /* This call looks bizarre, but it is required.  If the user
             entered a command that caused an error,
             after_char_processing_hook won't be called from
@@ -517,6 +450,8 @@ start_event_loop (void)
          /* Maybe better to set a flag to be checked somewhere as to
             whether display the prompt or not.  */
        }
+      if (result < 0)
+       break;
     }
 
   /* We are done with the event loop.  There are no more event sources
@@ -936,7 +871,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, TAIL);
+                 QUEUE_enque (gdb_event_p, event_queue, file_event_ptr);
                }
              file_ptr->ready_mask = (gdb_notifier.poll_fds + i)->revents;
            }
@@ -972,7 +907,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, TAIL);
+             QUEUE_enque (gdb_event_p, event_queue, file_event_ptr);
            }
          file_ptr->ready_mask = mask;
        }
@@ -1158,7 +1093,7 @@ check_async_event_handlers (void)
          data.ptr = hdata;
 
          event_ptr = create_event (invoke_async_event_handler, data);
-         async_queue_event (event_ptr, TAIL);
+         QUEUE_enque (gdb_event_p, event_queue, event_ptr);
        }
     }
 }
@@ -1365,7 +1300,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, TAIL);
+         QUEUE_enque (gdb_event_p, event_queue, event_ptr);
        }
 
       /* Now we need to update the timeout for select/ poll, because