public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v2] Restore terminal state in mi_thread_exit (PR gdb/17627)
@ 2014-12-02 22:10 Simon Marchi
  2014-12-03  0:09 ` Patrick Palka
  2014-12-04 15:35 ` Pedro Alves
  0 siblings, 2 replies; 8+ messages in thread
From: Simon Marchi @ 2014-12-02 22:10 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

When a thread exits, the terminal is left in mode "terminal_is_ours"
while the target executes. This patch fixes that.

From my understanding, a function calling target_terminal_ours expects
that the terminal could be in any state at the moment it is called.
Therefore, it should be its reponsibility to put back the terminal in
whatever state it was before being called.

I find that this fits quite well the cleanup model, so I implemented a
cleanup for that.

New in v2:

* Coding style fixes.
* Use make_cleanup_dtor instead of make_cleanup.

gdb/ChangeLog:

	PR gdb/17627
	* target.c (cleanup_restore_target_terminal): New function.
	(make_cleanup_restore_target_terminal): New function.
	* target.h (make_cleanup_restore_target_terminal): New
	declaration.
	* mi/mi-interp.c (mi_thread_exit): Use the new cleanup.

Signed-off-by: Simon Marchi <simon.marchi@ericsson.com>
---
 gdb/mi/mi-interp.c |  4 ++++
 gdb/target.c       | 34 ++++++++++++++++++++++++++++++++++
 gdb/target.h       |  4 ++++
 3 files changed, 42 insertions(+)

diff --git a/gdb/mi/mi-interp.c b/gdb/mi/mi-interp.c
index df2b558..60f0666 100644
--- a/gdb/mi/mi-interp.c
+++ b/gdb/mi/mi-interp.c
@@ -386,6 +386,7 @@ mi_thread_exit (struct thread_info *t, int silent)
 {
   struct mi_interp *mi;
   struct inferior *inf;
+  struct cleanup *old_chain;
 
   if (silent)
     return;
@@ -393,11 +394,14 @@ mi_thread_exit (struct thread_info *t, int silent)
   inf = find_inferior_pid (ptid_get_pid (t->ptid));
 
   mi = top_level_interpreter_data ();
+  old_chain = make_cleanup_restore_target_terminal ();
   target_terminal_ours ();
   fprintf_unfiltered (mi->event_channel, 
 		      "thread-exited,id=\"%d\",group-id=\"i%d\"",
 		      t->num, inf->num);
   gdb_flush (mi->event_channel);
+
+  do_cleanups (old_chain);
 }
 
 /* Emit notification on changing the state of record.  */
diff --git a/gdb/target.c b/gdb/target.c
index ab5f2b9..7161e62 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -528,6 +528,40 @@ target_supports_terminal_ours (void)
   return 0;
 }
 
+/* Restore the terminal to its previous state (helper for
+   make_cleanup_restore_target_terminal). */
+
+static void
+cleanup_restore_target_terminal (void *arg)
+{
+  enum terminal_state *previous_state = arg;
+
+  switch (*previous_state)
+    {
+    case terminal_is_ours:
+      target_terminal_ours ();
+      break;
+    case terminal_is_ours_for_output:
+      target_terminal_ours_for_output ();
+      break;
+    case terminal_is_inferior:
+      target_terminal_inferior ();
+      break;
+    }
+}
+
+/* See target.h. */
+
+struct cleanup *
+make_cleanup_restore_target_terminal (void)
+{
+  enum terminal_state *ts = xmalloc (sizeof (*ts));
+
+  *ts = terminal_state;
+
+  return make_cleanup_dtor (cleanup_restore_target_terminal, ts, xfree);
+}
+
 static void
 tcomplain (void)
 {
diff --git a/gdb/target.h b/gdb/target.h
index d363b61..eb3220e 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -1413,6 +1413,10 @@ extern void target_terminal_ours (void);
 
 extern int target_supports_terminal_ours (void);
 
+/* Make a cleanup that restores the state of the terminal to the current
+   value.  */
+extern struct cleanup *make_cleanup_restore_target_terminal (void);
+
 /* Print useful information about our terminal status, if such a thing
    exists.  */
 
-- 
2.1.3

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2014-12-10 18:06 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-12-02 22:10 [PATCH v2] Restore terminal state in mi_thread_exit (PR gdb/17627) Simon Marchi
2014-12-03  0:09 ` Patrick Palka
2014-12-03 14:29   ` Simon Marchi
2014-12-04 15:40     ` Pedro Alves
2014-12-04 15:35 ` Pedro Alves
2014-12-05 16:12   ` Simon Marchi
2014-12-10 17:20     ` Pedro Alves
2014-12-10 18:06       ` Simon Marchi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).