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] Implement post_event for Python scripts.


On Wednesday 18 August 2010 19:13:29, Tom Tromey wrote:

> Pedro> The expedient way to fix this I guess would be to resurrect gdb_pipe
> Pedro> from that patch, so that we have a consistent way across hosts
> Pedro> to create a pipe.  

Okay, I've confirmed that the patch below on top of yesterday's (which
adds serial_pipe), works, and the python.exp:post_event test passes on
Windows/mingw32.   Replacing pipe with gdb_pipe alone is not enough,
as indeed pipes are not waitable entities.  I guess I will apply this
and yesterday's tomorrow if nobody objects.

> Pedro> I do agree that using pipes on common code to wake up the event loop
> Pedro> is tackling at the wrong level (we should have an abstracted way to
> Pedro> do this, using pipes on posix hosts, events on Windows, etc.), but,
> Pedro> I'm happy with a simpler way for now.
> 
> Any way is ok by me, but the existing event code in mingw-hdep.c looks
> pretty simple too.  I don't understand all of it, but I could try to
> make a patch taking this direction if you want.  Just let me know.

The thing is that that code is for gdb_select, not the event loop
per-se.  Hacking gdb_select to break out when we want to
wake up the event loop doesn't look abstractly right to me.
IMO, we have the event loop implemented upside down.  We have it
heavilly file descriptor / poll / select oriented on all hosts, and
shoehorn Windows in by having gdb_select be able to poll on
more descriptor types than Windows itself allows.  IMO, it should be
the other way around --- the select/poll code should be moved to
somewhere host dependent (posix-hdep.c, for example), and the event
loop should be host-abstracted at the wait-for-one-event level.  The
Windows implementation would look similar to gdb_select, but not
constrained by the `select' API.

But, I don't claim to have the clearer vision here, and I'm
certainly open to ideas and patches.  :-)

-- 
Pedro Alves

2010-08-19  Pedro Alves  <pedro@codesourcery.com>

	* python/python.c: Include "serial.h".
	(gdbpy_event_fds): Change type to `struct serial *' a array from
	int array.
	(gdbpy_run_events): Change parameters.  Use serial_readchar in
	place of read.
	(gdbpy_post_event): Use serial_write in place of write.
	(gdbpy_initialize_events): Use serial_pipe instead of pipe, and
	serial_async in place of add_file_handler.

---
 gdb/python/python.c |   22 +++++++++++++---------
 1 file changed, 13 insertions(+), 9 deletions(-)

Index: src/gdb/python/python.c
===================================================================
--- src.orig/gdb/python/python.c	2010-08-20 00:10:56.000000000 +0100
+++ src/gdb/python/python.c	2010-08-20 01:11:48.000000000 +0100
@@ -29,6 +29,7 @@
 #include "language.h"
 #include "exceptions.h"
 #include "event-loop.h"
+#include "serial.h"
 
 #include <ctype.h>
 
@@ -568,23 +569,25 @@ static struct gdbpy_event **gdbpy_event_
 
 /* We use a file handler, and not an async handler, so that we can
    wake up the main thread even when it is blocked in poll().  */
-static int gdbpy_event_fds[2];
+static struct serial *gdbpy_event_fds[2];
 
 /* The file handler callback.  This reads from the internal pipe, and
    then processes the Python event queue.  This will always be run in
    the main gdb thread.  */
+
 static void
-gdbpy_run_events (int err, gdb_client_data ignore)
+gdbpy_run_events (struct serial *scb, void *context)
 {
   struct cleanup *cleanup;
-  char buffer[100];
   int r;
 
   cleanup = ensure_python_env (get_current_arch (), current_language);
 
-  /* Just read whatever is available on the fd.  It is relatively
-     harmless if there are any bytes left over.  */
-  r = read (gdbpy_event_fds[0], buffer, sizeof (buffer));
+  /* Flush the fd.  Do this before flushing the events list, so that
+     any new event post afterwards is sure to re-awake the event
+     loop.  */
+  while (serial_readchar (gdbpy_event_fds[0], 0) >= 0)
+    ;
 
   while (gdbpy_event_list)
     {
@@ -640,7 +643,8 @@ gdbpy_post_event (PyObject *self, PyObje
   if (wakeup)
     {
       char c = 'q';		/* Anything. */
-      if (write (gdbpy_event_fds[1], &c, 1) != 1)
+
+      if (serial_write (gdbpy_event_fds[1], &c, 1))
         return PyErr_SetFromErrno (PyExc_IOError);
     }
 
@@ -651,10 +655,10 @@ gdbpy_post_event (PyObject *self, PyObje
 static void
 gdbpy_initialize_events (void)
 {
-  if (!pipe (gdbpy_event_fds))
+  if (serial_pipe (gdbpy_event_fds) == 0)
     {
       gdbpy_event_list_end = &gdbpy_event_list;
-      add_file_handler (gdbpy_event_fds[0], gdbpy_run_events, NULL);
+      serial_async (gdbpy_event_fds[0], gdbpy_run_events, NULL);
     }
 }
 


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