[RFC,1/7] gdbsupport: Add an event-pipe class.

Message ID 20210607170932.3954-2-jhb@FreeBSD.org
State New
Headers show
Series
  • FreeBSD target async mode and related refactoring
Related show

Commit Message

John Baldwin June 7, 2021, 5:09 p.m.
This pulls out the implementation of an event pipe used to implement
target async support in both linux-low.cc (gdbserver) and linux-nat.c
(gdb).

gdbsupport/ChangeLog:

	* Makefile.in: Rebuild.
	* Makefile.am (libgdbsupport_a_SOURCES): Add event-pipe.cc.
	* event-pipe.h: New file.
	* event-pipe.cc: New file.
---
 gdbsupport/ChangeLog     |   7 +++
 gdbsupport/Makefile.am   |   1 +
 gdbsupport/Makefile.in   |  21 ++++----
 gdbsupport/event-pipe.cc | 100 +++++++++++++++++++++++++++++++++++++++
 gdbsupport/event-pipe.h  |  55 +++++++++++++++++++++
 5 files changed, 175 insertions(+), 9 deletions(-)
 create mode 100644 gdbsupport/event-pipe.cc
 create mode 100644 gdbsupport/event-pipe.h

-- 
2.31.1

Patch

diff --git a/gdbsupport/ChangeLog b/gdbsupport/ChangeLog
index b790a97230..c953d87fbf 100644
--- a/gdbsupport/ChangeLog
+++ b/gdbsupport/ChangeLog
@@ -1,3 +1,10 @@ 
+2021-06-04  John Baldwin  <jhb@FreeBSD.org>
+
+	* Makefile.in: Rebuild.
+	* Makefile.am (libgdbsupport_a_SOURCES): Add event-pipe.cc.
+	* event-pipe.h: New file.
+	* event-pipe.cc: New file.
+
 2021-05-17  Andrew Burgess  <andrew.burgess@embecosm.com>
 
 	* .dir-locals.el: Set sentence-end-double-space for all modes, and
diff --git a/gdbsupport/Makefile.am b/gdbsupport/Makefile.am
index 6d4678c8c9..a7d78f8c26 100644
--- a/gdbsupport/Makefile.am
+++ b/gdbsupport/Makefile.am
@@ -48,6 +48,7 @@  libgdbsupport_a_SOURCES = \
     environ.cc \
     errors.cc \
     event-loop.cc \
+    event-pipe.cc \
     fileio.cc \
     filestuff.cc \
     format.cc \
diff --git a/gdbsupport/Makefile.in b/gdbsupport/Makefile.in
index d7f2d4914b..7ff5531998 100644
--- a/gdbsupport/Makefile.in
+++ b/gdbsupport/Makefile.in
@@ -150,15 +150,16 @@  am_libgdbsupport_a_OBJECTS = agent.$(OBJEXT) btrace-common.$(OBJEXT) \
 	common-exceptions.$(OBJEXT) common-inferior.$(OBJEXT) \
 	common-regcache.$(OBJEXT) common-utils.$(OBJEXT) \
 	environ.$(OBJEXT) errors.$(OBJEXT) event-loop.$(OBJEXT) \
-	fileio.$(OBJEXT) filestuff.$(OBJEXT) format.$(OBJEXT) \
-	gdb-dlfcn.$(OBJEXT) gdb_tilde_expand.$(OBJEXT) \
-	gdb_wait.$(OBJEXT) gdb_vecs.$(OBJEXT) job-control.$(OBJEXT) \
-	netstuff.$(OBJEXT) new-op.$(OBJEXT) pathstuff.$(OBJEXT) \
-	print-utils.$(OBJEXT) ptid.$(OBJEXT) rsp-low.$(OBJEXT) \
-	run-time-clock.$(OBJEXT) safe-strerror.$(OBJEXT) \
-	scoped_mmap.$(OBJEXT) search.$(OBJEXT) signals.$(OBJEXT) \
-	signals-state-save-restore.$(OBJEXT) tdesc.$(OBJEXT) \
-	thread-pool.$(OBJEXT) xml-utils.$(OBJEXT) $(am__objects_1)
+	event-pipe.$(OBJEXT) fileio.$(OBJEXT) filestuff.$(OBJEXT) \
+	format.$(OBJEXT) gdb-dlfcn.$(OBJEXT) \
+	gdb_tilde_expand.$(OBJEXT) gdb_wait.$(OBJEXT) \
+	gdb_vecs.$(OBJEXT) job-control.$(OBJEXT) netstuff.$(OBJEXT) \
+	new-op.$(OBJEXT) pathstuff.$(OBJEXT) print-utils.$(OBJEXT) \
+	ptid.$(OBJEXT) rsp-low.$(OBJEXT) run-time-clock.$(OBJEXT) \
+	safe-strerror.$(OBJEXT) scoped_mmap.$(OBJEXT) search.$(OBJEXT) \
+	signals.$(OBJEXT) signals-state-save-restore.$(OBJEXT) \
+	tdesc.$(OBJEXT) thread-pool.$(OBJEXT) xml-utils.$(OBJEXT) \
+	$(am__objects_1)
 libgdbsupport_a_OBJECTS = $(am_libgdbsupport_a_OBJECTS)
 AM_V_P = $(am__v_P_@AM_V@)
 am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
@@ -371,6 +372,7 @@  libgdbsupport_a_SOURCES = \
     environ.cc \
     errors.cc \
     event-loop.cc \
+    event-pipe.cc \
     fileio.cc \
     filestuff.cc \
     format.cc \
@@ -476,6 +478,7 @@  distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/environ.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/errors.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/event-loop.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/event-pipe.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fileio.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/filestuff.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/format.Po@am__quote@
diff --git a/gdbsupport/event-pipe.cc b/gdbsupport/event-pipe.cc
new file mode 100644
index 0000000000..b701be0b5a
--- /dev/null
+++ b/gdbsupport/event-pipe.cc
@@ -0,0 +1,100 @@ 
+/* Event pipe for GDB, the GNU debugger.
+
+   Copyright (C) 2021 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include "gdbsupport/common-defs.h"
+#include "gdbsupport/event-pipe.h"
+#include "gdbsupport/filestuff.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+event_pipe::~event_pipe ()
+{
+  if (active ())
+    close ();
+}
+
+/* Create a new pipe.  */
+
+bool
+event_pipe::open ()
+{
+  if (fds[0] != -1)
+    return false;
+
+  if (gdb_pipe_cloexec (fds) == -1)
+    return false;
+
+  if (fcntl (fds[0], F_SETFL, O_NONBLOCK) == -1 ||
+      fcntl (fds[1], F_SETFL, O_NONBLOCK) == -1) {
+    close ();
+    return false;
+  }
+
+  return true;
+}
+
+void
+event_pipe::close ()
+{
+  ::close (fds[0]);
+  ::close (fds[1]);
+  fds[0] = -1;
+  fds[1] = -1;
+}
+
+/* Get rid of any pending events in the pipe.  */
+
+void
+event_pipe::flush ()
+{
+  int ret;
+  char buf;
+
+  do
+    {
+      ret = read (fds[0], &buf, 1);
+    }
+  while (ret >= 0 || (ret == -1 && errno == EINTR));
+}
+
+/* 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.  */
+
+void
+event_pipe::mark ()
+{
+  int ret;
+
+  /* It doesn't really matter what the pipe contains, as long we end
+     up with something in it.  Might as well flush the previous
+     left-overs.  */
+  flush ();
+
+  do
+    {
+      ret = write (fds[1], "+", 1);
+    }
+  while (ret == -1 && errno == EINTR);
+
+  /* Ignore EAGAIN.  If the pipe is full, the event loop will already
+     be awakened anyway.  */
+}
diff --git a/gdbsupport/event-pipe.h b/gdbsupport/event-pipe.h
new file mode 100644
index 0000000000..1717ea6790
--- /dev/null
+++ b/gdbsupport/event-pipe.h
@@ -0,0 +1,55 @@ 
+/* Event pipe for GDB, the GNU debugger.
+
+   Copyright (C) 2021 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef COMMON_EVENT_PIPE_H
+#define COMMON_EVENT_PIPE_H
+
+/* An event pipe used as a waitable file in the event loop in place of
+   some other event not associated with a file descriptor.  */
+
+class event_pipe
+{
+public:
+  event_pipe() = default;
+  ~event_pipe();
+
+  /* Create a new pipe.  */
+  bool open ();
+
+  /* Close the pipe.  */
+  void close ();
+
+  /* True if the event pipe has been initialized.  */
+  bool active () const { return fds[0] != -1; }
+
+  /* The file descriptor of the waitable file to use in the event
+     loop.  */
+  int event_fd () const { return fds[0]; }
+
+  /* Flush the event pipe.  */
+  void flush ();
+
+  /* Put something in the pipe, so the event loop wakes up.  */
+  void mark ();
+private:
+  int fds[2] = { -1, -1 };
+};
+
+#endif /* COMMON_EVENT_PIPE_H */
+