Make input_fd be per UI

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.
This commit is contained in:
Pedro Alves 2016-06-21 01:11:47 +01:00
parent f38d3ad186
commit 41fd2b0f5d
8 changed files with 59 additions and 24 deletions

View 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)

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

View 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);

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

View 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

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

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

View File

@ -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. */