public inbox for gdb-cvs@sourceware.org
help / color / mirror / Atom feed
From: John Baldwin <jhb@sourceware.org>
To: gdb-cvs@sourceware.org
Subject: [binutils-gdb] inf-ptrace: Add an event_pipe to be used for async mode in subclasses.
Date: Tue, 22 Feb 2022 19:34:25 +0000 (GMT)	[thread overview]
Message-ID: <20220222193425.AE4C0389EC5A@sourceware.org> (raw)

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=b146ba14d7019e046f5691ffbffa1d852b798c72

commit b146ba14d7019e046f5691ffbffa1d852b798c72
Author: John Baldwin <jhb@FreeBSD.org>
Date:   Tue Feb 22 11:22:14 2022 -0800

    inf-ptrace: Add an event_pipe to be used for async mode in subclasses.
    
    Subclasses of inf_ptrace_target have to opt-in to using the event_pipe
    by implementing the can_async_p and async methods.  For subclasses
    which do this, inf_ptrace_target provides is_async_p, async_wait_fd
    and closes the pipe in the close target method.
    
    inf_ptrace_target also provides wrapper routines around the event pipe
    (async_file_open, async_file_close, async_file_flush, and
    async_file_mark) for use in target methods such as async.
    inf_ptrace_target also exports a static async_file_mark_if_open
    function which can be used in SIGCHLD signal handlers.

Diff:
---
 gdb/fbsd-nat.c   |  50 ++++------------------
 gdb/fbsd-nat.h   |   4 --
 gdb/inf-ptrace.c |  15 +++++++
 gdb/inf-ptrace.h |  30 ++++++++++++++
 gdb/linux-nat.c  | 123 +++++++++++--------------------------------------------
 gdb/linux-nat.h  |   4 --
 6 files changed, 78 insertions(+), 148 deletions(-)

diff --git a/gdb/fbsd-nat.c b/gdb/fbsd-nat.c
index 6f1f208160e..ba84265dd58 100644
--- a/gdb/fbsd-nat.c
+++ b/gdb/fbsd-nat.c
@@ -21,7 +21,6 @@
 #include "gdbsupport/block-signals.h"
 #include "gdbsupport/byte-vector.h"
 #include "gdbsupport/event-loop.h"
-#include "gdbsupport/event-pipe.h"
 #include "gdbcore.h"
 #include "inferior.h"
 #include "regcache.h"
@@ -932,8 +931,6 @@ fbsd_nat_target::update_thread_list ()
 
 /* Async mode support.  */
 
-static event_pipe fbsd_nat_event_pipe;
-
 /* Implement the "can_async_p" target method.  */
 
 bool
@@ -946,22 +943,6 @@ fbsd_nat_target::can_async_p ()
   return true;
 }
 
-/* Implement the "is_async_p" target method.  */
-
-bool
-fbsd_nat_target::is_async_p ()
-{
-  return fbsd_nat_event_pipe.is_open ();
-}
-
-/* Implement the "async_wait_fd" target method.  */
-
-int
-fbsd_nat_target::async_wait_fd ()
-{
-  return fbsd_nat_event_pipe.event_fd ();
-}
-
 /* SIGCHLD handler notifies the event-loop in async mode.  */
 
 static void
@@ -969,8 +950,7 @@ sigchld_handler (int signo)
 {
   int old_errno = errno;
 
-  if (fbsd_nat_event_pipe.is_open ())
-    fbsd_nat_event_pipe.mark ();
+  fbsd_nat_target::async_file_mark_if_open ();
 
   errno = old_errno;
 }
@@ -997,34 +977,22 @@ fbsd_nat_target::async (int enable)
 
   if (enable)
     {
-      if (!fbsd_nat_event_pipe.open ())
+      if (!async_file_open ())
 	internal_error (__FILE__, __LINE__, "failed to create event pipe.");
 
-      add_file_handler (fbsd_nat_event_pipe.event_fd (),
-			handle_target_event, NULL, "fbsd-nat");
+      add_file_handler (async_wait_fd (), handle_target_event, NULL, "fbsd-nat");
 
       /* Trigger a poll in case there are pending events to
 	 handle.  */
-      fbsd_nat_event_pipe.mark ();
+      async_file_mark ();
     }
   else
     {
-      delete_file_handler (fbsd_nat_event_pipe.event_fd ());
-      fbsd_nat_event_pipe.close ();
+      delete_file_handler (async_wait_fd ());
+      async_file_close ();
     }
 }
 
-/* Implement the "close" target method.  */
-
-void
-fbsd_nat_target::close ()
-{
-  if (is_async_p ())
-    async (0);
-
-  inf_ptrace_target::close ();
-}
-
 #ifdef TDP_RFPPWAIT
 /*
   To catch fork events, PT_FOLLOW_FORK is set on every traced process
@@ -1100,7 +1068,7 @@ fbsd_add_vfork_done (ptid_t pid)
   /* If we're in async mode, need to tell the event loop there's
      something here to process.  */
   if (target_is_async_p ())
-    fbsd_nat_event_pipe.mark ();
+    async_file_mark ();
 }
 
 /* Check for a pending vfork done event for a specific PID.  */
@@ -1499,7 +1467,7 @@ fbsd_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
 
   /* Ensure any subsequent events trigger a new event in the loop.  */
   if (is_async_p ())
-    fbsd_nat_event_pipe.flush ();
+    async_file_flush ();
 
   wptid = wait_1 (ptid, ourstatus, target_options);
 
@@ -1510,7 +1478,7 @@ fbsd_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
       && ((ourstatus->kind () != TARGET_WAITKIND_IGNORE
 	  && ourstatus->kind() != TARGET_WAITKIND_NO_RESUMED)
 	  || ptid != minus_one_ptid))
-    fbsd_nat_event_pipe.mark ();
+    async_file_mark ();
 
   fbsd_nat_debug_printf ("returning [%s], [%s]",
 			 target_pid_to_str (wptid).c_str (),
diff --git a/gdb/fbsd-nat.h b/gdb/fbsd-nat.h
index 0acfef2f1f1..2d9c6e19a2c 100644
--- a/gdb/fbsd-nat.h
+++ b/gdb/fbsd-nat.h
@@ -67,13 +67,9 @@ public:
   void update_thread_list () override;
 
   bool can_async_p () override;
-  bool is_async_p () override;
 
-  int async_wait_fd () override;
   void async (int) override;
 
-  void close () override;
-
   thread_control_capabilities get_thread_control_capabilities () override
   { return tc_schedlock; }
 
diff --git a/gdb/inf-ptrace.c b/gdb/inf-ptrace.c
index ebcc409b989..ea1fe4541f0 100644
--- a/gdb/inf-ptrace.c
+++ b/gdb/inf-ptrace.c
@@ -48,6 +48,9 @@ gdb_ptrace (PTRACE_TYPE_ARG1 request, ptid_t ptid, PTRACE_TYPE_ARG3 addr,
 #endif
 }
 
+/* The event pipe registered as a waitable file in the event loop.  */
+event_pipe inf_ptrace_target::m_event_pipe;
+
 inf_ptrace_target::~inf_ptrace_target ()
 {}
 
@@ -527,3 +530,15 @@ inf_ptrace_target::pid_to_str (ptid_t ptid)
 {
   return normal_pid_to_str (ptid);
 }
+
+/* Implement the "close" target method.  */
+
+void
+inf_ptrace_target::close ()
+{
+  /* Unregister from the event loop.  */
+  if (is_async_p ())
+    async (0);
+
+  inf_child_target::close ();
+}
diff --git a/gdb/inf-ptrace.h b/gdb/inf-ptrace.h
index 01b05f7d20e..62cc7778767 100644
--- a/gdb/inf-ptrace.h
+++ b/gdb/inf-ptrace.h
@@ -20,6 +20,7 @@
 #ifndef INF_PTRACE_H
 #define INF_PTRACE_H
 
+#include "gdbsupport/event-pipe.h"
 #include "inf-child.h"
 
 /* An abstract prototype ptrace target.  The client can override it
@@ -33,6 +34,8 @@ struct inf_ptrace_target : public inf_child_target
 
   void detach (inferior *inf, int) override;
 
+  void close () override;
+
   void resume (ptid_t, int, enum gdb_signal) override;
 
   ptid_t wait (ptid_t, struct target_waitstatus *, target_wait_flags) override;
@@ -57,7 +60,31 @@ struct inf_ptrace_target : public inf_child_target
 					ULONGEST offset, ULONGEST len,
 					ULONGEST *xfered_len) override;
 
+  bool is_async_p () override
+  { return m_event_pipe.is_open (); }
+
+  int async_wait_fd () override
+  { return m_event_pipe.event_fd (); }
+
+  /* Helper routine used from SIGCHLD handlers to signal the async
+     event pipe.  */
+  static void async_file_mark_if_open ()
+  {
+    if (m_event_pipe.is_open ())
+      m_event_pipe.mark ();
+  }
+
 protected:
+  /* Helper routines for interacting with the async event pipe.  */
+  bool async_file_open ()
+  { return m_event_pipe.open (); }
+  void async_file_close ()
+  { m_event_pipe.close (); }
+  void async_file_flush ()
+  { m_event_pipe.flush (); }
+  void async_file_mark ()
+  { m_event_pipe.mark (); }
+
   /* Cleanup the inferior after a successful ptrace detach.  */
   void detach_success (inferior *inf);
 
@@ -71,6 +98,9 @@ protected:
      Such targets will supply an appropriate definition for this
      function.  */
   virtual void post_startup_inferior (ptid_t ptid) = 0;
+
+private:
+  static event_pipe m_event_pipe;
 };
 
 #ifndef __NetBSD__
diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c
index 055da9a0cf2..13682fcff43 100644
--- a/gdb/linux-nat.c
+++ b/gdb/linux-nat.c
@@ -48,7 +48,6 @@
 #include <fcntl.h>		/* for O_RDONLY */
 #include "inf-loop.h"
 #include "gdbsupport/event-loop.h"
-#include "gdbsupport/event-pipe.h"
 #include "event-top.h"
 #include <pwd.h>
 #include <sys/types.h>
@@ -66,6 +65,7 @@
 #include "gdbsupport/filestuff.h"
 #include "objfiles.h"
 #include "nat/linux-namespaces.h"
+#include "gdbsupport/block-signals.h"
 #include "gdbsupport/fileio.h"
 #include "gdbsupport/scope-exit.h"
 #include "gdbsupport/gdb-sigmask.h"
@@ -227,32 +227,6 @@ static struct simple_pid_list *stopped_pids;
 /* Whether target_thread_events is in effect.  */
 static int report_thread_events;
 
-/* Async mode support.  */
-
-/* The event pipe registered as a waitable file in the event loop.  */
-static event_pipe linux_nat_event_pipe;
-
-/* True if we're currently in async mode.  */
-#define linux_is_async_p() (linux_nat_event_pipe.is_open ())
-
-/* Flush the event pipe.  */
-
-static void
-async_file_flush (void)
-{
-  linux_nat_event_pipe.flush ();
-}
-
-/* Put something (anything, doesn't matter what, or how much) in event
-   pipe, so that the select/poll in the event-loop realizes we have
-   something to process.  */
-
-static void
-async_file_mark (void)
-{
-  linux_nat_event_pipe.mark ();
-}
-
 static int kill_lwp (int lwpid, int signo);
 
 static int stop_callback (struct lwp_info *lp);
@@ -4054,14 +4028,6 @@ linux_nat_target::static_tracepoint_markers_by_strid (const char *strid)
   return markers;
 }
 
-/* target_is_async_p implementation.  */
-
-bool
-linux_nat_target::is_async_p ()
-{
-  return linux_is_async_p ();
-}
-
 /* target_can_async_p implementation.  */
 
 bool
@@ -4113,10 +4079,11 @@ sigchld_handler (int signo)
   if (debug_linux_nat)
     gdb_stdlog->write_async_safe ("sigchld\n", sizeof ("sigchld\n") - 1);
 
-  if (signo == SIGCHLD
-      && linux_nat_event_pipe.is_open ())
-    async_file_mark (); /* Let the event loop know that there are
-			   events to handle.  */
+  if (signo == SIGCHLD)
+    {
+      /* Let the event loop know that there are events to handle.  */
+      linux_nat_target::async_file_mark_if_open ();
+    }
 
   errno = old_errno;
 }
@@ -4129,67 +4096,35 @@ handle_target_event (int error, gdb_client_data client_data)
   inferior_event_handler (INF_REG_EVENT);
 }
 
-/* Create/destroy the target events pipe.  Returns previous state.  */
-
-static int
-linux_async_pipe (int enable)
-{
-  int previous = linux_is_async_p ();
-
-  if (previous != enable)
-    {
-      sigset_t prev_mask;
-
-      /* Block child signals while we create/destroy the pipe, as
-	 their handler writes to it.  */
-      block_child_signals (&prev_mask);
-
-      if (enable)
-	{
-	  if (!linux_nat_event_pipe.open ())
-	    internal_error (__FILE__, __LINE__,
-			    "creating event pipe failed.");
-	}
-      else
-	{
-	  linux_nat_event_pipe.close ();
-	}
-
-      restore_child_signals_mask (&prev_mask);
-    }
-
-  return previous;
-}
-
-int
-linux_nat_target::async_wait_fd ()
-{
-  return linux_nat_event_pipe.event_fd ();
-}
-
 /* target_async implementation.  */
 
 void
 linux_nat_target::async (int enable)
 {
+  if ((enable != 0) == is_async_p ())
+    return;
+
+  /* Block child signals while we create/destroy the pipe, as their
+     handler writes to it.  */
+  gdb::block_signals blocker;
+
   if (enable)
     {
-      if (!linux_async_pipe (1))
-	{
-	  add_file_handler (linux_nat_event_pipe.event_fd (),
-			    handle_target_event, NULL,
-			    "linux-nat");
-	  /* There may be pending events to handle.  Tell the event loop
-	     to poll them.  */
-	  async_file_mark ();
-	}
+      if (!async_file_open ())
+	internal_error (__FILE__, __LINE__, "creating event pipe failed.");
+
+      add_file_handler (async_wait_fd (), handle_target_event, NULL,
+			"linux-nat");
+
+      /* There may be pending events to handle.  Tell the event loop
+	 to poll them.  */
+      async_file_mark ();
     }
   else
     {
-      delete_file_handler (linux_nat_event_pipe.event_fd ());
-      linux_async_pipe (0);
+      delete_file_handler (async_wait_fd ());
+      async_file_close ();
     }
-  return;
 }
 
 /* Stop an LWP, and push a GDB_SIGNAL_0 stop status if no other
@@ -4238,16 +4173,6 @@ linux_nat_target::stop (ptid_t ptid)
   iterate_over_lwps (ptid, linux_nat_stop_lwp);
 }
 
-void
-linux_nat_target::close ()
-{
-  /* Unregister from the event loop.  */
-  if (is_async_p ())
-    async (0);
-
-  inf_ptrace_target::close ();
-}
-
 /* When requests are passed down from the linux-nat layer to the
    single threaded inf-ptrace layer, ptids of (lwpid,0,0) form are
    used.  The address space pointer is stored in the inferior object,
diff --git a/gdb/linux-nat.h b/gdb/linux-nat.h
index befe5b6311a..12a90eccb28 100644
--- a/gdb/linux-nat.h
+++ b/gdb/linux-nat.h
@@ -83,16 +83,12 @@ public:
   void thread_events (int) override;
 
   bool can_async_p () override;
-  bool is_async_p () override;
 
   bool supports_non_stop () override;
   bool always_non_stop_p () override;
 
-  int async_wait_fd () override;
   void async (int) override;
 
-  void close () override;
-
   void stop (ptid_t) override;
 
   bool supports_multi_process () override;


                 reply	other threads:[~2022-02-22 19:34 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220222193425.AE4C0389EC5A@sourceware.org \
    --to=jhb@sourceware.org \
    --cc=gdb-cvs@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).