From patchwork Wed Feb 3 16:43:44 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pedro Alves X-Patchwork-Id: 10725 Received: (qmail 74726 invoked by alias); 3 Feb 2016 16:52:48 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 74714 invoked by uid 89); 3 Feb 2016 16:52:48 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.3 required=5.0 tests=BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=auxvh, UD:auxv.h, auxv.h, wakes X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Wed, 03 Feb 2016 16:52:47 +0000 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 5A62B38251D for ; Wed, 3 Feb 2016 16:44:07 +0000 (UTC) Received: from brno.lan (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u13GhwPR022971 for ; Wed, 3 Feb 2016 11:44:06 -0500 From: Pedro Alves To: gdb-patches@sourceware.org Subject: [PATCH 09/23] Make input_fd be per UI Date: Wed, 3 Feb 2016 16:43:44 +0000 Message-Id: <1454517838-7784-10-git-send-email-palves@redhat.com> In-Reply-To: <1454517838-7784-1-git-send-email-palves@redhat.com> References: <1454517838-7784-1-git-send-email-palves@redhat.com> 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/event-top.c | 33 ++++++++++++++------------------- gdb/event-top.h | 1 - gdb/linux-nat.c | 2 -- gdb/main.c | 1 + gdb/remote.c | 2 -- gdb/target.c | 10 ++++++++++ gdb/top.h | 4 ++++ 7 files changed, 29 insertions(+), 24 deletions(-) diff --git a/gdb/event-top.c b/gdb/event-top.c index ddeaf80..c94b365 100644 --- a/gdb/event-top.c +++ b/gdb/event-top.c @@ -95,10 +95,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. */ @@ -412,12 +408,16 @@ get_line_builder (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); } @@ -1040,18 +1040,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 @@ -1060,6 +1053,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 @@ -1074,5 +1069,5 @@ gdb_disable_readline (void) #endif gdb_rl_callback_handler_remove (); - delete_file_handler (input_fd); + delete_file_handler (ui->input_fd); } diff --git a/gdb/event-top.h b/gdb/event-top.h index 4f89626..1b2cc59 100644 --- a/gdb/event-top.h +++ b/gdb/event-top.h @@ -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_callback_no_editing (void *client_data); diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c index 6ded38d..614231a 100644 --- a/gdb/linux-nat.c +++ b/gdb/linux-nat.c @@ -4292,7 +4292,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 (); } @@ -4318,7 +4317,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; } diff --git a/gdb/main.c b/gdb/main.c index 89037cf..eee9a8b 100644 --- a/gdb/main.c +++ b/gdb/main.c @@ -507,6 +507,7 @@ captured_main (void *data) clear_quit_flag (); 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 diff --git a/gdb/remote.c b/gdb/remote.c index 8831b50..52f44e0 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -5948,7 +5948,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; async_initialize_sigint_signal_handler (); /* NOTE: At this point we could also register our selves as the @@ -5967,7 +5966,6 @@ remote_terminal_ours (struct target_ops *self) if (remote_async_terminal_ours_p) return; async_cleanup_sigint_signal_handler (NULL); - add_file_handler (input_fd, stdin_event_handler, 0); remote_async_terminal_ours_p = 1; } diff --git a/gdb/target.c b/gdb/target.c index ac66a3a..86e7074 100644 --- a/gdb/target.c +++ b/gdb/target.c @@ -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,8 @@ target_terminal_inferior (void) if (target_can_async_p () && !sync_execution) return; + delete_file_handler (ui->input_fd); + if (terminal_state == terminal_is_inferior) return; @@ -498,6 +504,10 @@ target_terminal_inferior (void) void target_terminal_ours (void) { + struct ui *ui = current_ui; + + add_file_handler (ui->input_fd, stdin_event_handler, ui); + if (terminal_state == terminal_is_ours) return; diff --git a/gdb/top.h b/gdb/top.h index 6937eb3..ef50489 100644 --- a/gdb/top.h +++ b/gdb/top.h @@ -73,6 +73,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 serial object that wraps stdin. */ struct serial *stdin_serial;