summaryrefslogtreecommitdiffstats
path: root/lldb/source/Host/posix/ConnectionFileDescriptorPosix.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Host/posix/ConnectionFileDescriptorPosix.cpp')
-rw-r--r--lldb/source/Host/posix/ConnectionFileDescriptorPosix.cpp99
1 files changed, 19 insertions, 80 deletions
diff --git a/lldb/source/Host/posix/ConnectionFileDescriptorPosix.cpp b/lldb/source/Host/posix/ConnectionFileDescriptorPosix.cpp
index 5d6a8938e00..a6d0958c8c6 100644
--- a/lldb/source/Host/posix/ConnectionFileDescriptorPosix.cpp
+++ b/lldb/source/Host/posix/ConnectionFileDescriptorPosix.cpp
@@ -20,6 +20,7 @@
#include "lldb/Host/SocketAddress.h"
#include "lldb/Host/Socket.h"
#include "lldb/Host/StringConvert.h"
+#include "lldb/Utility/SelectHelper.h"
// C Includes
#include <errno.h>
@@ -572,7 +573,7 @@ ConnectionFileDescriptor::GetURI()
return m_uri;
}
-// This ConnectionFileDescriptor::BytesAvailable() uses select().
+// This ConnectionFileDescriptor::BytesAvailable() uses select() via SelectHelper
//
// PROS:
// - select is consistent across most unix platforms
@@ -586,11 +587,6 @@ ConnectionFileDescriptor::GetURI()
// be used or a new version of ConnectionFileDescriptor::BytesAvailable()
// should be written for the system that is running into the limitations.
-#if defined(__APPLE__)
-#define FD_SET_DATA(fds) fds.data()
-#else
-#define FD_SET_DATA(fds) &fds
-#endif
ConnectionStatus
ConnectionFileDescriptor::BytesAvailable(uint32_t timeout_usec, Error *error_ptr)
@@ -602,21 +598,6 @@ ConnectionFileDescriptor::BytesAvailable(uint32_t timeout_usec, Error *error_ptr
if (log)
log->Printf("%p ConnectionFileDescriptor::BytesAvailable (timeout_usec = %u)", static_cast<void *>(this), timeout_usec);
- struct timeval *tv_ptr;
- struct timeval tv;
- if (timeout_usec == UINT32_MAX)
- {
- // Infinite wait...
- tv_ptr = nullptr;
- }
- else
- {
- TimeValue time_value;
- time_value.OffsetWithMicroSeconds(timeout_usec);
- tv.tv_sec = time_value.seconds();
- tv.tv_usec = time_value.microseconds();
- tv_ptr = &tv;
- }
// Make a copy of the file descriptors to make sure we don't
// have another thread change these values out from under us
@@ -624,8 +605,14 @@ ConnectionFileDescriptor::BytesAvailable(uint32_t timeout_usec, Error *error_ptr
const IOObject::WaitableHandle handle = m_read_sp->GetWaitableHandle();
const int pipe_fd = m_pipe.GetReadFileDescriptor();
+
if (handle != IOObject::kInvalidHandleValue)
{
+ SelectHelper select_helper;
+ if (timeout_usec != UINT32_MAX)
+ select_helper.SetTimeout(std::chrono::microseconds(timeout_usec));
+
+ select_helper.FDSetRead(handle);
#if defined(_MSC_VER)
// select() won't accept pipes on Windows. The entire Windows codepath needs to be
// converted over to using WaitForMultipleObjects and event HANDLEs, but for now at least
@@ -633,62 +620,14 @@ ConnectionFileDescriptor::BytesAvailable(uint32_t timeout_usec, Error *error_ptr
const bool have_pipe_fd = false;
#else
const bool have_pipe_fd = pipe_fd >= 0;
-#if !defined(__APPLE__)
- assert(handle < FD_SETSIZE);
- if (have_pipe_fd)
- assert(pipe_fd < FD_SETSIZE);
-#endif
#endif
+ if (have_pipe_fd)
+ select_helper.FDSetRead(pipe_fd);
+
while (handle == m_read_sp->GetWaitableHandle())
{
- const int nfds = std::max<int>(handle, pipe_fd) + 1;
-#if defined(__APPLE__)
- llvm::SmallVector<fd_set, 1> read_fds;
- read_fds.resize((nfds / FD_SETSIZE) + 1);
- for (size_t i = 0; i < read_fds.size(); ++i)
- FD_ZERO(&read_fds[i]);
-// FD_SET doesn't bounds check, it just happily walks off the end
-// but we have taken care of making the extra storage with our
-// SmallVector of fd_set objects
-#else
- fd_set read_fds;
- FD_ZERO(&read_fds);
-#endif
- FD_SET(handle, FD_SET_DATA(read_fds));
- if (have_pipe_fd)
- FD_SET(pipe_fd, FD_SET_DATA(read_fds));
- Error error;
-
- if (log)
- {
- if (have_pipe_fd)
- log->Printf(
- "%p ConnectionFileDescriptor::BytesAvailable() ::select (nfds=%i, fds={%i, %i}, NULL, NULL, timeout=%p)...",
- static_cast<void *>(this), nfds, handle, pipe_fd, static_cast<void *>(tv_ptr));
- else
- log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::select (nfds=%i, fds={%i}, NULL, NULL, timeout=%p)...",
- static_cast<void *>(this), nfds, handle, static_cast<void *>(tv_ptr));
- }
-
- const int num_set_fds = ::select(nfds, FD_SET_DATA(read_fds), NULL, NULL, tv_ptr);
- if (num_set_fds < 0)
- error.SetErrorToErrno();
- else
- error.Clear();
-
- if (log)
- {
- if (have_pipe_fd)
- log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::select (nfds=%i, fds={%i, %i}, NULL, NULL, timeout=%p) "
- "=> %d, error = %s",
- static_cast<void *>(this), nfds, handle, pipe_fd, static_cast<void *>(tv_ptr), num_set_fds,
- error.AsCString());
- else
- log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::select (nfds=%i, fds={%i}, NULL, NULL, timeout=%p) => "
- "%d, error = %s",
- static_cast<void *>(this), nfds, handle, static_cast<void *>(tv_ptr), num_set_fds, error.AsCString());
- }
+ Error error = select_helper.Select();
if (error_ptr)
*error_ptr = error;
@@ -704,6 +643,9 @@ ConnectionFileDescriptor::BytesAvailable(uint32_t timeout_usec, Error *error_ptr
default: // Other unknown error
return eConnectionStatusError;
+ case ETIMEDOUT:
+ return eConnectionStatusTimedOut;
+
case EAGAIN: // The kernel was (perhaps temporarily) unable to
// allocate the requested number of file descriptors,
// or we have non-blocking IO
@@ -713,15 +655,12 @@ ConnectionFileDescriptor::BytesAvailable(uint32_t timeout_usec, Error *error_ptr
break; // Lets keep reading to until we timeout
}
}
- else if (num_set_fds == 0)
- {
- return eConnectionStatusTimedOut;
- }
- else if (num_set_fds > 0)
+ else
{
- if (FD_ISSET(handle, FD_SET_DATA(read_fds)))
+ if (select_helper.FDIsSetRead(handle))
return eConnectionStatusSuccess;
- if (have_pipe_fd && FD_ISSET(pipe_fd, FD_SET_DATA(read_fds)))
+
+ if (select_helper.FDIsSetRead(pipe_fd))
{
// There is an interrupt or exit command in the command pipe
// Read the data from that pipe:
OpenPOWER on IntegriCloud