Make input_fd be per UI
authorPedro Alves <palves@redhat.com>
Tue, 21 Jun 2016 00:11:47 +0000 (01:11 +0100)
committerPedro Alves <palves@redhat.com>
Tue, 21 Jun 2016 00:11:47 +0000 (01:11 +0100)
And with that, we can switch the current UI to the UI whose input
descriptor woke up the event loop.  IOW, if the user types in UI 2,
the event loop wakes up, switches to UI 2, and processes the input.
Next the user types in UI 3, the event loop wakes up and switches to
UI 3, etc.

gdb/ChangeLog:
2016-06-21  Pedro Alves  <palves@redhat.com>

* event-top.c (input_fd): Delete.
(stdin_event_handler): Switch to the UI whose input descriptor got
the event.  Adjust to per-UI input_fd.
(gdb_setup_readline): Don't set the input_fd global.  Adjust to
per-UI input_fd.
(gdb_disable_readline): Adjust to per-UI input_fd.
* event-top.h (input_fd): Delete declaration.
* linux-nat.c (linux_nat_terminal_inferior): Don't remove input_fd
from the event-loop here.
(linux_nat_terminal_ours): Don't register input_fd in the
event-loop here.
* main.c (captured_main): Adjust to per-UI input_fd.
* remote.c (remote_terminal_inferior): Don't remove input_fd from
the event-loop here.
(remote_terminal_ours): Don't register input_fd in the event-loop
here.
* target.c: Include top.h and event-top.h.
(target_terminal_inferior): Remove input_fd from the event-loop
here.
(target_terminal_ours): Register input_fd in the event-loop.
* top.h (struct ui) <input_fd>: New field.

gdb/ChangeLog
gdb/event-top.c
gdb/event-top.h
gdb/linux-nat.c
gdb/main.c
gdb/remote.c
gdb/target.c
gdb/top.h

index c1ebfe9d405526dabe0f35924c06eff8466ee26c..680e6e5913a222cd91f7e9a330bea70b8c71b68e 100644 (file)
@@ -1,3 +1,27 @@
+2016-06-21  Pedro Alves  <palves@redhat.com>
+
+       * event-top.c (input_fd): Delete.
+       (stdin_event_handler): Switch to the UI whose input descriptor got
+       the event.  Adjust to per-UI input_fd.
+       (gdb_setup_readline): Don't set the input_fd global.  Adjust to
+       per-UI input_fd.
+       (gdb_disable_readline): Adjust to per-UI input_fd.
+       * event-top.h (input_fd): Delete declaration.
+       * linux-nat.c (linux_nat_terminal_inferior): Don't remove input_fd
+       from the event-loop here.
+       (linux_nat_terminal_ours): Don't register input_fd in the
+       event-loop here.
+       * main.c (captured_main): Adjust to per-UI input_fd.
+       * remote.c (remote_terminal_inferior): Don't remove input_fd from
+       the event-loop here.
+       (remote_terminal_ours): Don't register input_fd in the event-loop
+       here.
+       * target.c: Include top.h and event-top.h.
+       (target_terminal_inferior): Remove input_fd from the event-loop
+       here.
+       (target_terminal_ours): Register input_fd in the event-loop.
+       * top.h (struct ui) <input_fd>: New field.
+
 2016-06-21  Pedro Alves  <palves@redhat.com>
 
        * cli/cli-script.c (execute_user_command, read_next_line)
index 3e2f778b0324ea15d539464e3f1530fb1d9061a7..1d36b81682ac7f832f08d3de5b44a45a2b0f03d5 100644 (file)
@@ -94,10 +94,6 @@ int async_command_editing_p;
    asynchronous execution command.  */
 int exec_done_display_p = 0;
 
-/* This is the file descriptor for the input stream that GDB uses to
-   read commands from.  */
-int input_fd;
-
 /* Used by the stdin event handler to compensate for missed stdin events.
    Setting this to a non-zero value inside an stdin callback makes the callback
    run again.  */
@@ -503,12 +499,16 @@ get_command_line_buffer (void)
 void
 stdin_event_handler (int error, gdb_client_data client_data)
 {
-  struct ui *ui = current_ui;
+  struct ui *ui = (struct ui *) client_data;
+
+  /* Switch to the UI whose input descriptor woke up the event
+     loop.  */
+  current_ui = ui;
 
   if (error)
     {
       printf_unfiltered (_("error detected on stdin\n"));
-      delete_file_handler (input_fd);
+      delete_file_handler (ui->input_fd);
       /* If stdin died, we may as well kill gdb.  */
       quit_command ((char *) 0, stdin == ui->instream);
     }
@@ -1270,18 +1270,11 @@ gdb_setup_readline (void)
   /* Tell readline to use the same input stream that gdb uses.  */
   rl_instream = ui->instream;
 
-  /* Get a file descriptor for the input stream, so that we can
-     register it with the event loop.  */
-  input_fd = fileno (ui->instream);
-
-  /* Now we need to create the event sources for the input file
-     descriptor.  */
-  /* At this point in time, this is the only event source that we
-     register with the even loop.  Another source is going to be the
-     target program (inferior), but that must be registered only when
-     it actually exists (I.e. after we say 'run' or after we connect
-     to a remote target.  */
-  add_file_handler (input_fd, stdin_event_handler, 0);
+  /* Now create the event source for this UI's input file descriptor.
+     Another source is going to be the target program (inferior), but
+     that must be registered only when it actually exists (I.e. after
+     we say 'run' or after we connect to a remote target.  */
+  add_file_handler (ui->input_fd, stdin_event_handler, ui);
 }
 
 /* Disable command input through the standard CLI channels.  Used in
@@ -1290,6 +1283,8 @@ gdb_setup_readline (void)
 void
 gdb_disable_readline (void)
 {
+  struct ui *ui = current_ui;
+
   /* FIXME - It is too heavyweight to delete and remake these every
      time you run an interpreter that needs readline.  It is probably
      better to have the interpreters cache these, which in turn means
@@ -1304,5 +1299,5 @@ gdb_disable_readline (void)
 #endif
 
   gdb_rl_callback_handler_remove ();
-  delete_file_handler (input_fd);
+  delete_file_handler (ui->input_fd);
 }
index 04956a5579dd6198ceeb88f0060bbebe3c98a5ac..4fe773711328fdb5e1b3a622fb0a05ef2ae7766a 100644 (file)
@@ -57,7 +57,6 @@ extern void async_enable_stdin (void);
 extern int async_command_editing_p;
 extern int exec_done_display_p;
 extern struct prompts the_prompts;
-extern int input_fd;
 extern void (*after_char_processing_hook) (void);
 extern int call_stdin_event_handler_again_p;
 extern void gdb_readline_no_editing_callback (void *client_data);
index e6d525ffc1600147a1fcdf8fa6703b257aafb30b..fd2df5f8ca583634303f693716a6282185adcadf 100644 (file)
@@ -4415,7 +4415,6 @@ linux_nat_terminal_inferior (struct target_ops *self)
   if (!async_terminal_is_ours)
     return;
 
-  delete_file_handler (input_fd);
   async_terminal_is_ours = 0;
   set_sigint_trap ();
 }
@@ -4441,7 +4440,6 @@ linux_nat_terminal_ours (struct target_ops *self)
     return;
 
   clear_sigint_trap ();
-  add_file_handler (input_fd, stdin_event_handler, 0);
   async_terminal_is_ours = 1;
 }
 
index 2b763a3da5d0ac77410e30e6b3422f68405f7760..87bf05af705a50be14e402c57bc07842e0c418ef 100644 (file)
@@ -508,6 +508,7 @@ captured_main (void *data)
 
   saved_command_line = (char *) xstrdup ("");
   ui->instream = stdin;
+  ui->input_fd = fileno (stdin);
 
 #ifdef __MINGW32__
   /* Ensure stderr is unbuffered.  A Cygwin pty or pipe is implemented
index 1f0d67cfddf865bff04b12977638a527df570870..501f3c63bd44ba8f5ac5cef45205732c590e508a 100644 (file)
@@ -5924,7 +5924,6 @@ remote_terminal_inferior (struct target_ops *self)
      can go away.  */
   if (!remote_async_terminal_ours_p)
     return;
-  delete_file_handler (input_fd);
   remote_async_terminal_ours_p = 0;
   /* NOTE: At this point we could also register our selves as the
      recipient of all input.  Any characters typed could then be
@@ -5937,7 +5936,6 @@ remote_terminal_ours (struct target_ops *self)
   /* See FIXME in remote_terminal_inferior.  */
   if (remote_async_terminal_ours_p)
     return;
-  add_file_handler (input_fd, stdin_event_handler, 0);
   remote_async_terminal_ours_p = 1;
 }
 
index c0ce46ddde864e0d52e57c25e6f27f67c11ea8f7..b53074a41c88944088f8520b40197869c81e42c9 100644 (file)
@@ -43,6 +43,8 @@
 #include "agent.h"
 #include "auxv.h"
 #include "target-debug.h"
+#include "top.h"
+#include "event-top.h"
 
 static void target_info (char *, int);
 
@@ -477,6 +479,8 @@ target_terminal_is_ours (void)
 void
 target_terminal_inferior (void)
 {
+  struct ui *ui = current_ui;
+
   /* A background resume (``run&'') should leave GDB in control of the
      terminal.  Use target_can_async_p, not target_is_async_p, since at
      this point the target is not async yet.  However, if sync_execution
@@ -484,6 +488,11 @@ target_terminal_inferior (void)
   if (target_can_async_p () && !sync_execution)
     return;
 
+  /* Always delete the current UI's input file handler, regardless of
+     terminal_state, because terminal_state is only valid for the main
+     UI.  */
+  delete_file_handler (ui->input_fd);
+
   if (terminal_state == terminal_is_inferior)
     return;
 
@@ -503,6 +512,13 @@ target_terminal_inferior (void)
 void
 target_terminal_ours (void)
 {
+  struct ui *ui = current_ui;
+
+  /* Always add the current UI's input file handler, regardless of
+     terminal_state, because terminal_state is only valid for the main
+     UI.  */
+  add_file_handler (ui->input_fd, stdin_event_handler, ui);
+
   if (terminal_state == terminal_is_ours)
     return;
 
index 1e00acb743796c2978a9938173a965449eae1b7c..8990277dfd58eb799dce398e064eab4662d832ba 100644 (file)
--- a/gdb/top.h
+++ b/gdb/top.h
@@ -74,6 +74,10 @@ struct ui
      interacting via a GUI.  */
   FILE *instream;
 
+  /* The file descriptor for the input stream, so that we can register
+     it with the event loop.  */
+  int input_fd;
+
   /* The fields below that start with "m_" are "private".  They're
      meant to be accessed through wrapper macros that make them look
      like globals.  */