]> granicus.if.org Git - llvm/commitdiff
Revert "[Support] Add RetryAfterSignal helper function" and subsequent fix
authorPavel Labath <labath@google.com>
Thu, 22 Jun 2017 14:18:55 +0000 (14:18 +0000)
committerPavel Labath <labath@google.com>
Thu, 22 Jun 2017 14:18:55 +0000 (14:18 +0000)
The fix in r306003 uncovered a pretty fundamental problem that libc++
implementation of std::result_of does not handle the prototype of
open(2) correctly (presumably because it contains ...). This makes the
whole function unusable in its current form, so I am also reverting the
original commit (r305892), which introduced the function, at least until
I figure out a way to solve the libc++ issue.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@306005 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Support/Errno.h
lib/Support/MemoryBuffer.cpp
lib/Support/Unix/Path.inc
lib/Support/Unix/Process.inc
unittests/Support/CMakeLists.txt
unittests/Support/ErrnoTest.cpp [deleted file]

index 201b5598c02912933e1b516430ac8cd0a6ccf796..4ce65e7dc83c5c65d6d992d8c6e62aeca3ccf109 100644 (file)
@@ -16,7 +16,6 @@
 
 #include <cerrno>
 #include <string>
-#include <type_traits>
 
 namespace llvm {
 namespace sys {
@@ -30,18 +29,6 @@ std::string StrError();
 /// Like the no-argument version above, but uses \p errnum instead of errno.
 std::string StrError(int errnum);
 
-template <typename Fun, typename... Args,
-          typename ResultT = std::result_of<Fun const &(const Args &...)>>
-inline typename ResultT::type RetryAfterSignal(typename ResultT::type Fail,
-                                               const Fun &F,
-                                               const Args &... As) {
-  typename ResultT::type Res;
-  do
-    Res = F(As...);
-  while (Res == Fail && errno == EINTR);
-  return Res;
-}
-
 }  // namespace sys
 }  // namespace llvm
 
index 85e782b2c048ac33861defb4e92989692d58287f..227e792d83dc477a97bfdb396b030c8712be7fb8 100644 (file)
@@ -240,9 +240,11 @@ getMemoryBufferForStream(int FD, const Twine &BufferName) {
   // Read into Buffer until we hit EOF.
   do {
     Buffer.reserve(Buffer.size() + ChunkSize);
-    ReadBytes = sys::RetryAfterSignal(-1, read, FD, Buffer.end(), ChunkSize);
-    if (ReadBytes == -1)
+    ReadBytes = read(FD, Buffer.end(), ChunkSize);
+    if (ReadBytes == -1) {
+      if (errno == EINTR) continue;
       return std::error_code(errno, std::generic_category());
+    }
     Buffer.set_size(Buffer.size() + ReadBytes);
   } while (ReadBytes != 0);
 
@@ -389,12 +391,13 @@ getOpenFileImpl(int FD, const Twine &Filename, uint64_t FileSize,
 
   while (BytesLeft) {
 #ifdef HAVE_PREAD
-    ssize_t NumRead = sys::RetryAfterSignal(-1, ::pread, FD, BufPtr, BytesLeft,
-                                            MapSize - BytesLeft + Offset);
+    ssize_t NumRead = ::pread(FD, BufPtr, BytesLeft, MapSize-BytesLeft+Offset);
 #else
-    ssize_t NumRead = sys::RetryAfterSignal(-1, ::read, FD, BufPtr, BytesLeft);
+    ssize_t NumRead = ::read(FD, BufPtr, BytesLeft);
 #endif
     if (NumRead == -1) {
+      if (errno == EINTR)
+        continue;
       // Error while reading.
       return std::error_code(errno, std::generic_category());
     }
index 45097eb918b7c9fb018c0366c0f80f1090e458a5..b6774692595bd1a5892047228c505f7105e7fb98 100644 (file)
@@ -737,8 +737,10 @@ std::error_code openFileForRead(const Twine &Name, int &ResultFD,
 #ifdef O_CLOEXEC
   OpenFlags |= O_CLOEXEC;
 #endif
-  if ((ResultFD = sys::RetryAfterSignal(-1, open, P.begin(), OpenFlags)) < 0)
-    return std::error_code(errno, std::generic_category());
+  while ((ResultFD = open(P.begin(), OpenFlags)) < 0) {
+    if (errno != EINTR)
+      return std::error_code(errno, std::generic_category());
+  }
 #ifndef O_CLOEXEC
   int r = fcntl(ResultFD, F_SETFD, FD_CLOEXEC);
   (void)r;
@@ -798,8 +800,10 @@ std::error_code openFileForWrite(const Twine &Name, int &ResultFD,
 
   SmallString<128> Storage;
   StringRef P = Name.toNullTerminatedStringRef(Storage);
-  if ((ResultFD = sys::RetryAfterSignal(-1, open, P.begin(), OpenFlags, Mode)) < 0)
-    return std::error_code(errno, std::generic_category());
+  while ((ResultFD = open(P.begin(), OpenFlags, Mode)) < 0) {
+    if (errno != EINTR)
+      return std::error_code(errno, std::generic_category());
+  }
 #ifndef O_CLOEXEC
   int r = fcntl(ResultFD, F_SETFD, FD_CLOEXEC);
   (void)r;
index 2d4662094682fad2adabec0c8d8ea35cd5a3787c..1d0143c6716e00edd9d99054644fd139e60ed45f 100644 (file)
@@ -207,10 +207,13 @@ std::error_code Process::FixupStandardFileDescriptors() {
   for (int StandardFD : StandardFDs) {
     struct stat st;
     errno = 0;
-    if (RetryAfterSignal(-1, fstat, StandardFD, &st) < 0) {
+    while (fstat(StandardFD, &st) < 0) {
       assert(errno && "expected errno to be set if fstat failed!");
       // fstat should return EBADF if the file descriptor is closed.
-      if (errno != EBADF)
+      if (errno == EBADF)
+        break;
+      // retry fstat if we got EINTR, otherwise bubble up the failure.
+      if (errno != EINTR)
         return std::error_code(errno, std::generic_category());
     }
     // if fstat succeeds, move on to the next FD.
@@ -219,8 +222,11 @@ std::error_code Process::FixupStandardFileDescriptors() {
     assert(errno == EBADF && "expected errno to have EBADF at this point!");
 
     if (NullFD < 0) {
-      if ((NullFD = RetryAfterSignal(-1, open, "/dev/null", O_RDWR)) < 0)
+      while ((NullFD = open("/dev/null", O_RDWR)) < 0) {
+        if (errno == EINTR)
+          continue;
         return std::error_code(errno, std::generic_category());
+      }
     }
 
     if (NullFD == StandardFD)
index 641163e39ed3c91f6d31b0e0939d5a11259b1c16..e2a6561089bc2f4c8f2735b97a7831684b32a3e9 100644 (file)
@@ -21,7 +21,6 @@ add_llvm_unittest(SupportTests
   DebugTest.cpp
   EndianStreamTest.cpp
   EndianTest.cpp
-  ErrnoTest.cpp
   ErrorOrTest.cpp
   ErrorTest.cpp
   FileOutputBufferTest.cpp
diff --git a/unittests/Support/ErrnoTest.cpp b/unittests/Support/ErrnoTest.cpp
deleted file mode 100644 (file)
index 888c162..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-//===- ErrnoTest.cpp - Error handling unit tests --------------------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Support/Errno.h"
-#include "gtest/gtest.h"
-
-using namespace llvm::sys;
-
-static int *ReturnPointer() { return new int(47); }
-
-TEST(ErrnoTest, RetryAfterSignal) {
-  EXPECT_EQ(1, RetryAfterSignal(-1, [] { return 1; }));
-
-  EXPECT_EQ(-1, RetryAfterSignal(-1, [] {
-    errno = EAGAIN;
-    return -1;
-  }));
-  EXPECT_EQ(EAGAIN, errno);
-
-  unsigned calls = 0;
-  EXPECT_EQ(1, RetryAfterSignal(-1, [&calls] {
-              errno = EINTR;
-              ++calls;
-              return calls == 1 ? -1 : 1;
-            }));
-  EXPECT_EQ(2u, calls);
-
-  EXPECT_EQ(1, RetryAfterSignal(-1, [](int x) { return x; }, 1));
-
-  std::unique_ptr<int> P{RetryAfterSignal(nullptr, ReturnPointer)};
-  EXPECT_EQ(47, *P);
-}