Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Pedro Alves <pedro@palves.net>
To: Kamil Rytarowski <kamil@netbsd.org>,
	Simon Marchi <simark@simark.ca>,
	gdb-patches@sourceware.org
Cc: tom@tromey.com
Subject: [PATCH] gdb::handle_eintr, remove need to specify return type (Re: [PATCH v2 01/10] Add handle_eintr to wrap EINTR handling in syscalls)
Date: Mon, 12 Oct 2020 18:56:32 +0100	[thread overview]
Message-ID: <75070000-03a2-eeed-4f72-e29f199291af@palves.net> (raw)
In-Reply-To: <bb5edc30-a021-899c-b532-9245a40662ca@netbsd.org>

Hi!

On 9/7/20 3:59 PM, Kamil Rytarowski wrote:
> On 07.09.2020 16:06, Simon Marchi wrote:
>> On 2020-09-03 8:28 p.m., Kamil Rytarowski wrote:

>>> +#ifndef GDBSUPPORT_EINTR_H
>>> +#define GDBSUPPORT_EINTR_H
>>> +
>>> +#include <cerrno>
>>> +
>>> +namespace gdb
>>> +{
>>> +template <typename Ret, typename Fun, typename... Args>
>>> +inline Ret handle_eintr (const Ret &R, const Fun &F, const Args &... A)
>>> +{
>>> +  Ret ret;
>>> +  do
>>> +    {
>>> +      errno = 0;
>>> +      ret = F (A...);
>>> +    }
>>> +  while (ret == R && errno == EINTR);
>>> +  return ret;
>>> +}
>>> +}
>>
>> Can you document this function a little bit, including a usage example?  I tried
>> to apply it in gdb/linux-nat.c, function async_file_mark, but I'm not sure I'm
>> doing it correctly.  In particular, what should I pass as the `R` parameter?  Does
>> that make sense?
>>
> 
> I'm going to add an example and some documentation.
> 
>>   gdb::handle_eintr (-1, ::write, linux_nat_event_pipe[1], "+", 1);
>>
> 
> gdb::handle_eintr<ssize_t> (-1, ::write, linux_nat_event_pipe[1], "+", 1);

Going through my email backlog I noticed this.

This requirement to explicitly specify the return type at each caller
seems unnecessary.  We can make the compiler deduce it for us based on
the return type of the wrapped function.  I gave it a shot -- do you see
an issue with the change below?

I adjusted the NetBSD files, but I don't have an easy way to confirm
they still build OK, though I expect they do.

I converted Linux's my_waitpid to use the adjusted handle_eintr, and
it worked OK.

From 0c2cf066f3f34a9aa3de7aab7bc2bca80b557b45 Mon Sep 17 00:00:00 2001
From: Pedro Alves <pedro@palves.net>
Date: Tue, 8 Sep 2020 17:34:41 +0100
Subject: [PATCH] gdb::handle_eintr, remove need to specify return type

This eliminates the need to specify the return type when using
handle_eintr.  We let the compiler deduce it for us.

Also, use lowercase for function parameter names.  Uppercase should
only be used on template parameters.

gdb/ChangeLog:

	* nat/linux-waitpid.c: Include "gdbsupport/eintr.h".
	(my_waitpid): Use gdb::handle_eintr.

gdbserver/ChangeLog:

	* netbsd-low.cc (netbsd_waitpid, netbsd_process_target::kill)
	(netbsd_qxfer_libraries_svr4): Use gdb::handle_eintr without
	explicit type.

gdbsupport/ChangeLog:

	* eintr.h: Include "gdbsupport/traits.h".
	(handle_eintr): Replace Ret template parameter with ErrorValType.
	Use it as type of the failure value.  Deduce the function's return
	type using gdb::return_type.  Use lowercase for function parameter
	names.
	* traits.h (struct return_type): New.
---
 gdb/nat/linux-waitpid.c | 11 ++---------
 gdbserver/netbsd-low.cc | 10 +++++-----
 gdbsupport/eintr.h      | 29 ++++++++++++++++++-----------
 gdbsupport/traits.h     | 11 +++++++++++
 4 files changed, 36 insertions(+), 25 deletions(-)

diff --git a/gdb/nat/linux-waitpid.c b/gdb/nat/linux-waitpid.c
index f50e0c7bcff..d066239220a 100644
--- a/gdb/nat/linux-waitpid.c
+++ b/gdb/nat/linux-waitpid.c
@@ -22,6 +22,7 @@
 #include "linux-nat.h"
 #include "linux-waitpid.h"
 #include "gdbsupport/gdb_wait.h"
+#include "gdbsupport/eintr.h"
 
 /* Convert wait status STATUS to a string.  Used for printing debug
    messages only.  */
@@ -54,13 +55,5 @@ status_to_str (int status)
 int
 my_waitpid (int pid, int *status, int flags)
 {
-  int ret;
-
-  do
-    {
-      ret = waitpid (pid, status, flags);
-    }
-  while (ret == -1 && errno == EINTR);
-
-  return ret;
+  return gdb::handle_eintr (-1, ::waitpid, pid, status, flags);
 }
diff --git a/gdbserver/netbsd-low.cc b/gdbserver/netbsd-low.cc
index 30028d3a384..519614d0473 100644
--- a/gdbserver/netbsd-low.cc
+++ b/gdbserver/netbsd-low.cc
@@ -245,7 +245,7 @@ netbsd_waitpid (ptid_t ptid, struct target_waitstatus *ourstatus,
   int options = (target_options & TARGET_WNOHANG) ? WNOHANG : 0;
 
   pid_t pid
-    = gdb::handle_eintr<int> (-1, ::waitpid, ptid.pid (), &status, options);
+    = gdb::handle_eintr (-1, ::waitpid, ptid.pid (), &status, options);
 
   if (pid == -1)
     perror_with_name (_("Child process unexpectedly missing"));
@@ -456,7 +456,7 @@ netbsd_process_target::kill (process_info *process)
     return -1;
 
   int status;
-  if (gdb::handle_eintr<int> (-1, ::waitpid, pid, &status, 0) == -1)
+  if (gdb::handle_eintr (-1, ::waitpid, pid, &status, 0) == -1)
     return -1;
   mourn (process);
   return 0;
@@ -1149,15 +1149,15 @@ netbsd_qxfer_libraries_svr4 (const pid_t pid, const char *annex,
 static bool
 elf_64_file_p (const char *file)
 {
-  int fd = gdb::handle_eintr<int> (-1, ::open, file, O_RDONLY);
+  int fd = gdb::handle_eintr (-1, ::open, file, O_RDONLY);
   if (fd < 0)
     perror_with_name (("open"));
 
   Elf64_Ehdr header;
-  ssize_t ret = gdb::handle_eintr<ssize_t> (-1, ::read, fd, &header, sizeof (header));
+  ssize_t ret = gdb::handle_eintr (-1, ::read, fd, &header, sizeof (header));
   if (ret == -1)
     perror_with_name (("read"));
-  gdb::handle_eintr<int> (-1, ::close, fd);
+  gdb::handle_eintr (-1, ::close, fd);
   if (ret != sizeof (header))
     error ("Cannot read ELF file header: %s", file);
 
diff --git a/gdbsupport/eintr.h b/gdbsupport/eintr.h
index 64ff5940b75..ab8310e561c 100644
--- a/gdbsupport/eintr.h
+++ b/gdbsupport/eintr.h
@@ -22,6 +22,8 @@
 
 #include <cerrno>
 
+#include "gdbsupport/traits.h"
+
 namespace gdb
 {
 /* Repeat a system call interrupted with a signal.
@@ -43,25 +45,30 @@ namespace gdb
 
    You could wrap it by writing the wrapped form:
 
-   ssize_t ret = gdb::handle_eintr<ssize_t> (-1, ::write, pipe[1], "+", 1);
+   ssize_t ret = gdb::handle_eintr (-1, ::write, pipe[1], "+", 1);
 
-   The RET typename specifies the return type of the wrapped system call, which
-   is typically int or ssize_t.  The R argument specifies the failure value
-   indicating the interrupted syscall when calling the F function with
-   the A... arguments.  */
+   ERRVAL specifies the failure value indicating that the call to the
+   F function with ARGS... arguments was possibly interrupted with a
+   signal.  */
 
-template <typename Ret, typename Fun, typename... Args>
-inline Ret handle_eintr (const Ret &R, const Fun &F, const Args &... A)
+template <typename ErrorValType,
+	  typename Fun,
+	  typename... Args>
+inline typename return_type<Fun>::type
+handle_eintr (ErrorValType errval, const Fun &f, const Args &... args)
 {
-  Ret ret;
+  typename return_type<Fun>::type ret;
+
   do
     {
       errno = 0;
-      ret = F (A...);
+      ret = f (args...);
     }
-  while (ret == R && errno == EINTR);
+  while (ret == errval && errno == EINTR);
+
   return ret;
 }
-}
+
+} /* namespace gdb */
 
 #endif /* GDBSUPPORT_EINTR_H */
diff --git a/gdbsupport/traits.h b/gdbsupport/traits.h
index 93b609ac109..f161ca00fa6 100644
--- a/gdbsupport/traits.h
+++ b/gdbsupport/traits.h
@@ -43,6 +43,17 @@
 
 namespace gdb {
 
+/* Use partial specialization to get access a function's return
+   type.  */
+template<class Signature>
+struct return_type;
+
+template<typename Res, typename... Args>
+struct return_type<Res (Args...)>
+{
+  typedef Res type;
+};
+
 /* Pre C++14-safe (CWG 1558) version of C++17's std::void_t.  See
    <http://en.cppreference.com/w/cpp/types/void_t>.  */
 

base-commit: 87a37e5e078f506fa9905b74e9238593c537fcd5
-- 
2.14.5


  reply	other threads:[~2020-10-12 17:56 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-09-04  0:28 [PATCH v2 00/10] Add minimal NetBSD/amd64 gdbserver support Kamil Rytarowski
2020-09-04  0:28 ` [PATCH v2 01/10] Add handle_eintr to wrap EINTR handling in syscalls Kamil Rytarowski
2020-09-07 14:06   ` Simon Marchi
2020-09-07 14:59     ` Kamil Rytarowski
2020-10-12 17:56       ` Pedro Alves [this message]
2020-10-13 13:43         ` [PATCH] gdb::handle_eintr, remove need to specify return type (Re: [PATCH v2 01/10] Add handle_eintr to wrap EINTR handling in syscalls) Kamil Rytarowski
2020-10-13 14:17           ` [PATCH v2] gdb::handle_eintr, remove need to specify return type Pedro Alves
2020-10-13 14:54             ` Kamil Rytarowski
2020-10-16 20:51             ` Tom Tromey
2020-10-26 14:00               ` Pedro Alves
2020-10-26 14:20                 ` Tom Tromey
2020-10-26 18:59                   ` Pedro Alves
2020-09-04  0:28 ` [PATCH v2 02/10] Register a placeholder for NetBSD shared functions in gdb/nat Kamil Rytarowski
2020-09-07 18:44   ` Simon Marchi
2020-09-07 19:49     ` Kamil Rytarowski
2020-09-04  0:28 ` [PATCH v2 03/10] Build nat/netbsd-nat.o for the NetBSD native target Kamil Rytarowski
2020-09-04  0:28 ` [PATCH v2 04/10] Add netbsd_nat::pid_to_exec_file Kamil Rytarowski
2020-09-07  7:57   ` Andrew Burgess
2020-09-07 13:36     ` Kamil Rytarowski
2020-09-07 18:48       ` Simon Marchi
2020-09-07 18:47   ` Simon Marchi
2020-09-07 19:51     ` Kamil Rytarowski
2020-09-04  0:29 ` [PATCH v2 05/10] Add gdb/nat common functions for listing threads Kamil Rytarowski
2020-09-07 18:59   ` Simon Marchi
2020-09-07 19:57     ` Kamil Rytarowski
2020-09-04  0:29 ` [PATCH v2 06/10] Add netbsd_nat::enable_proc_events in gdb/nat Kamil Rytarowski
2020-09-04  0:29 ` [PATCH v2 07/10] Add a common utility function to read and write siginfo_t in inferior Kamil Rytarowski
2020-09-04  0:29 ` [PATCH v2 08/10] Avoid double free in startup_inferior Kamil Rytarowski
2020-09-07 19:19   ` Simon Marchi
2020-09-08  0:54     ` Kamil Rytarowski
2020-09-08  2:21       ` Simon Marchi
2020-09-04  0:29 ` [PATCH v2 09/10] Switch local native code to gdb/nat shared functions Kamil Rytarowski
2020-09-07 19:24   ` Simon Marchi
2020-09-08  0:04     ` Kamil Rytarowski
2020-09-04  0:29 ` [PATCH v2 10/10] Add minimal and functional NetBSD/amd64 gdbserver Kamil Rytarowski
2020-09-07 19:58   ` Simon Marchi
2020-09-08  0:03     ` Kamil Rytarowski

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=75070000-03a2-eeed-4f72-e29f199291af@palves.net \
    --to=pedro@palves.net \
    --cc=gdb-patches@sourceware.org \
    --cc=kamil@netbsd.org \
    --cc=simark@simark.ca \
    --cc=tom@tromey.com \
    /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