labath updated this revision to Diff 101212.
labath added a comment.
- fix freebsd typo
- use ::waitpid consistently
https://reviews.llvm.org/D33831
Files:
include/lldb/Host/Host.h
source/Host/common/File.cpp
source/Host/macosx/Host.mm
source/Host/posix/ConnectionFileDescriptorPosix.cpp
source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
source/Plugins/Process/Linux/NativeProcessLinux.cpp
source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
unittests/Host/CMakeLists.txt
unittests/Host/HostTest.cpp
Index: unittests/Host/HostTest.cpp
===================================================================
--- /dev/null
+++ unittests/Host/HostTest.cpp
@@ -0,0 +1,33 @@
+//===-- HostTest.cpp --------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Host/Host.h"
+#include "gtest/gtest.h"
+
+using namespace lldb_private;
+
+TEST(Host, temp_failure_retry) {
+ EXPECT_EQ(1, temp_failure_retry(-1, [] { return 1; }));
+
+ EXPECT_EQ(-1, temp_failure_retry(-1, [] {
+ errno = EAGAIN;
+ return -1;
+ }));
+ EXPECT_EQ(EAGAIN, errno);
+
+ unsigned calls = 0;
+ EXPECT_EQ(1, temp_failure_retry(-1, [&calls] {
+ errno = EINTR;
+ ++calls;
+ return calls == 1 ? -1 : 1;
+ }));
+ EXPECT_EQ(2u, calls);
+
+ EXPECT_EQ(1, temp_failure_retry(-1, [](int x) { return x; }, 1));
+}
Index: unittests/Host/CMakeLists.txt
===================================================================
--- unittests/Host/CMakeLists.txt
+++ unittests/Host/CMakeLists.txt
@@ -1,6 +1,7 @@
set (FILES
FileSpecTest.cpp
FileSystemTest.cpp
+ HostTest.cpp
MainLoopTest.cpp
SocketAddressTest.cpp
SocketTest.cpp
Index: source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
===================================================================
--- source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
+++ source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
@@ -848,15 +848,13 @@
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
// Process all pending waitpid notifications.
int status;
- ::pid_t wait_pid = waitpid(GetID(), &status, WALLSIG | WNOHANG);
+ ::pid_t wait_pid =
+ temp_failure_retry(-1, waitpid, GetID(), &status, WALLSIG | WNOHANG);
if (wait_pid == 0)
return; // We are done.
if (wait_pid == -1) {
- if (errno == EINTR)
- return;
-
Status error(errno, eErrorTypePOSIX);
LLDB_LOG(log, "waitpid ({0}, &status, _) failed: {1}", GetID(), error);
}
Index: source/Plugins/Process/Linux/NativeProcessLinux.cpp
===================================================================
--- source/Plugins/Process/Linux/NativeProcessLinux.cpp
+++ source/Plugins/Process/Linux/NativeProcessLinux.cpp
@@ -688,14 +688,11 @@
// The thread is not tracked yet, let's wait for it to appear.
int status = -1;
- ::pid_t wait_pid;
- do {
- LLDB_LOG(log,
- "received thread creation event for tid {0}. tid not tracked "
- "yet, waiting for thread to appear...",
- tid);
- wait_pid = waitpid(tid, &status, __WALL);
- } while (wait_pid == -1 && errno == EINTR);
+ LLDB_LOG(log,
+ "received thread creation event for tid {0}. tid not tracked "
+ "yet, waiting for thread to appear...",
+ tid);
+ ::pid_t wait_pid = temp_failure_retry(-1, ::waitpid, tid, &status, __WALL);
// Since we are waiting on a specific tid, this must be the creation event.
// But let's do some checks just in case.
if (wait_pid != tid) {
@@ -2370,15 +2367,13 @@
// Process all pending waitpid notifications.
while (true) {
int status = -1;
- ::pid_t wait_pid = waitpid(-1, &status, __WALL | __WNOTHREAD | WNOHANG);
+ ::pid_t wait_pid = temp_failure_retry(-1, ::waitpid, -1, &status,
+ __WALL | __WNOTHREAD | WNOHANG);
if (wait_pid == 0)
break; // We are done.
if (wait_pid == -1) {
- if (errno == EINTR)
- continue;
-
Status error(errno, eErrorTypePOSIX);
LLDB_LOG(log, "waitpid (-1, &status, _) failed: {0}", error);
break;
Index: source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
===================================================================
--- source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
+++ source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
@@ -747,15 +747,9 @@
if (!error.Success())
return;
-WAIT_AGAIN:
- // Wait for the operation thread to initialize.
- if (sem_wait(&args->m_semaphore)) {
- if (errno == EINTR)
- goto WAIT_AGAIN;
- else {
- error.SetErrorToErrno();
- return;
- }
+ if (temp_failure_retry(-1, sem_wait, &args->m_semaphore) == -1) {
+ error.SetErrorToErrno();
+ return;
}
// Check that the launch was a success.
@@ -791,15 +785,9 @@
if (!error.Success())
return;
-WAIT_AGAIN:
- // Wait for the operation thread to initialize.
- if (sem_wait(&args->m_semaphore)) {
- if (errno == EINTR)
- goto WAIT_AGAIN;
- else {
- error.SetErrorToErrno();
- return;
- }
+ if (temp_failure_retry(-1, sem_wait, &args->m_semaphore) == -1) {
+ error.SetErrorToErrno();
+ return;
}
// Check that the attach was a success.
Index: source/Host/posix/ConnectionFileDescriptorPosix.cpp
===================================================================
--- source/Host/posix/ConnectionFileDescriptorPosix.cpp
+++ source/Host/posix/ConnectionFileDescriptorPosix.cpp
@@ -245,11 +245,7 @@
} else if ((addr = GetURLAddress(path, FILE_SCHEME))) {
std::string addr_str = addr->str();
// file:///PATH
- int fd = -1;
- do {
- fd = ::open(addr_str.c_str(), O_RDWR);
- } while (fd == -1 && errno == EINTR);
-
+ int fd = temp_failure_retry(-1, ::open, addr_str.c_str(), O_RDWR);
if (fd == -1) {
if (error_ptr)
error_ptr->SetErrorToErrno();
@@ -622,20 +618,17 @@
if (select_helper.FDIsSetRead(pipe_fd)) {
// There is an interrupt or exit command in the command pipe
// Read the data from that pipe:
- char buffer[1];
-
- ssize_t bytes_read;
-
- do {
- bytes_read = ::read(pipe_fd, buffer, sizeof(buffer));
- } while (bytes_read < 0 && errno == EINTR);
+ char c;
- switch (buffer[0]) {
+ ssize_t bytes_read = temp_failure_retry(-1, ::read, pipe_fd, &c, 1);
+ assert(bytes_read == 1);
+ (void)bytes_read;
+ switch (c) {
case 'q':
if (log)
log->Printf("%p ConnectionFileDescriptor::BytesAvailable() "
"got data: %c from the command channel.",
- static_cast<void *>(this), buffer[0]);
+ static_cast<void *>(this), c);
return eConnectionStatusEndOfFile;
case 'i':
// Interrupt the current read
Index: source/Host/macosx/Host.mm
===================================================================
--- source/Host/macosx/Host.mm
+++ source/Host/macosx/Host.mm
@@ -1367,10 +1367,7 @@
int wait_pid = 0;
bool cancel = false;
bool exited = false;
- do {
- wait_pid = ::waitpid(pid, &status, 0);
- } while (wait_pid < 0 && errno == EINTR);
-
+ wait_pid = temp_failure_retry(-1, ::waitpid, pid, &status, 0);
if (wait_pid >= 0) {
int signal = 0;
int exit_status = 0;
Index: source/Host/common/File.cpp
===================================================================
--- source/Host/common/File.cpp
+++ source/Host/common/File.cpp
@@ -28,6 +28,7 @@
#include "llvm/Support/Process.h" // for llvm::sys::Process::FileDescriptorHasColors()
#include "lldb/Host/Config.h"
+#include "lldb/Host/Host.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Log.h"
@@ -133,9 +134,7 @@
m_should_close_fd = true;
}
- do {
- m_stream = ::fdopen(m_descriptor, mode);
- } while (m_stream == NULL && errno == EINTR);
+ m_stream = temp_failure_retry(nullptr, ::fdopen, m_descriptor, mode);
// If we got a stream, then we own the stream and should no
// longer own the descriptor because fclose() will close it for us
@@ -157,6 +156,19 @@
m_own_stream = transfer_ownership;
}
+static int DoOpen(const char *path, int flags, int mode) {
+#ifdef _MSC_VER
+ std::wstring wpath;
+ if (!llvm::ConvertUTF8toWide(path, wpath))
+ return -1;
+ int result;
+ ::_wsopen_s(&result, wpath.c_str(), oflag, _SH_DENYNO, mode);
+ return result;
+#else
+ return ::open(path, flags, mode);
+#endif
+}
+
Status File::Open(const char *path, uint32_t options, uint32_t permissions) {
Status error;
if (IsValid())
@@ -222,20 +234,7 @@
mode |= S_IXOTH;
}
- do {
-#ifdef _MSC_VER
- std::wstring wpath;
- if (!llvm::ConvertUTF8toWide(path, wpath)) {
- m_descriptor = -1;
- error.SetErrorString("Error converting path to UTF-16");
- return error;
- }
- ::_wsopen_s(&m_descriptor, wpath.c_str(), oflag, _SH_DENYNO, mode);
-#else
- m_descriptor = ::open(path, oflag, mode);
-#endif
- } while (m_descriptor < 0 && errno == EINTR);
-
+ m_descriptor = temp_failure_retry(-1, DoOpen, path, oflag, mode);
if (!DescriptorIsValid())
error.SetErrorToErrno();
else {
@@ -421,12 +420,7 @@
Status File::Flush() {
Status error;
if (StreamIsValid()) {
- int err = 0;
- do {
- err = ::fflush(m_stream);
- } while (err == EOF && errno == EINTR);
-
- if (err == EOF)
+ if (temp_failure_retry(EOF, ::fflush, m_stream) == EOF)
error.SetErrorToErrno();
} else if (!DescriptorIsValid()) {
error.SetErrorString("invalid file handle");
@@ -442,12 +436,7 @@
if (err == 0)
error.SetErrorToGenericError();
#else
- int err = 0;
- do {
- err = ::fsync(m_descriptor);
- } while (err == -1 && errno == EINTR);
-
- if (err == -1)
+ if (temp_failure_retry(-1, ::fsync, m_descriptor) == -1)
error.SetErrorToErrno();
#endif
} else {
@@ -497,10 +486,7 @@
ssize_t bytes_read = -1;
if (DescriptorIsValid()) {
- do {
- bytes_read = ::read(m_descriptor, buf, num_bytes);
- } while (bytes_read < 0 && errno == EINTR);
-
+ bytes_read = temp_failure_retry(-1, ::read, m_descriptor, buf, num_bytes);
if (bytes_read == -1) {
error.SetErrorToErrno();
num_bytes = 0;
@@ -559,10 +545,8 @@
ssize_t bytes_written = -1;
if (DescriptorIsValid()) {
- do {
- bytes_written = ::write(m_descriptor, buf, num_bytes);
- } while (bytes_written < 0 && errno == EINTR);
-
+ bytes_written =
+ temp_failure_retry(-1, ::write, m_descriptor, buf, num_bytes);
if (bytes_written == -1) {
error.SetErrorToErrno();
num_bytes = 0;
@@ -624,11 +608,8 @@
#ifndef _WIN32
int fd = GetDescriptor();
if (fd != kInvalidDescriptor) {
- ssize_t bytes_read = -1;
- do {
- bytes_read = ::pread(fd, buf, num_bytes, offset);
- } while (bytes_read < 0 && errno == EINTR);
-
+ ssize_t bytes_read =
+ temp_failure_retry(-1, ::pread, fd, buf, num_bytes, offset);
if (bytes_read < 0) {
num_bytes = 0;
error.SetErrorToErrno();
@@ -730,11 +711,8 @@
int fd = GetDescriptor();
if (fd != kInvalidDescriptor) {
#ifndef _WIN32
- ssize_t bytes_written = -1;
- do {
- bytes_written = ::pwrite(m_descriptor, buf, num_bytes, offset);
- } while (bytes_written < 0 && errno == EINTR);
-
+ ssize_t bytes_written =
+ temp_failure_retry(-1, ::pwrite, m_descriptor, buf, num_bytes, offset);
if (bytes_written < 0) {
num_bytes = 0;
error.SetErrorToErrno();
Index: include/lldb/Host/Host.h
===================================================================
--- include/lldb/Host/Host.h
+++ include/lldb/Host/Host.h
@@ -7,21 +7,20 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_Host_h_
-#define liblldb_Host_h_
-#if defined(__cplusplus)
-
-#include <stdarg.h>
-
-#include <map>
-#include <string>
+#ifndef LLDB_HOST_HOST_H
+#define LLDB_HOST_HOST_H
#include "lldb/Host/File.h"
#include "lldb/Host/HostThread.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/StringList.h"
#include "lldb/lldb-private-forward.h"
#include "lldb/lldb-private.h"
+#include <cerrno>
+#include <map>
+#include <stdarg.h>
+#include <string>
+#include <type_traits>
namespace lldb_private {
@@ -244,7 +243,16 @@
static size_t GetEnvironment(StringList &env);
};
+template <typename R, typename F, typename... Args>
+inline auto temp_failure_retry(const R &fail_value, const F &f,
+ const Args &... args) -> decltype(f(args...)) {
+ decltype(f(args...)) result;
+ do
+ result = f(args...);
+ while (result == fail_value && errno == EINTR);
+ return result;
+}
+
} // namespace lldb_private
-#endif // #if defined(__cplusplus)
-#endif // liblldb_Host_h_
+#endif // LLDB_HOST_HOST_H
_______________________________________________
lldb-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits