[Lldb-commits] [lldb] r210592 - Remove duplicated code
Ed Maste
emaste at freebsd.org
Tue Jun 10 14:33:43 PDT 2014
Author: emaste
Date: Tue Jun 10 16:33:43 2014
New Revision: 210592
URL: http://llvm.org/viewvc/llvm-project?rev=210592&view=rev
Log:
Remove duplicated code
We preivously had two copies of ::BytesAvailable with only trivial
differences between them, and fixes have been applied to only one of
them.
Instead of duplicating the whole function, hide the FD_SET differences
behind a macro. This leaves only one small __APPLE__-specific #if
block, and fixes ^C on non-__APPLE__ platforms.
Modified:
lldb/trunk/source/Core/ConnectionFileDescriptor.cpp
Modified: lldb/trunk/source/Core/ConnectionFileDescriptor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ConnectionFileDescriptor.cpp?rev=210592&r1=210591&r2=210592&view=diff
==============================================================================
--- lldb/trunk/source/Core/ConnectionFileDescriptor.cpp (original)
+++ lldb/trunk/source/Core/ConnectionFileDescriptor.cpp Tue Jun 10 16:33:43 2014
@@ -707,18 +707,19 @@ ConnectionFileDescriptor::Write (const v
-#if defined(__APPLE__)
-
// This ConnectionFileDescriptor::BytesAvailable() uses select().
//
// PROS:
// - select is consistent across most unix platforms
-// - this Apple specific version allows for unlimited fds in the fd_sets by
+// - The Apple specific version allows for unlimited fds in the fd_sets by
// setting the _DARWIN_UNLIMITED_SELECT define prior to including the
// required header files.
-// CONS:
-// - Darwin only
+#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)
@@ -755,10 +756,16 @@ ConnectionFileDescriptor::BytesAvailable
if (data_fd >= 0)
{
const bool have_pipe_fd = pipe_fd >= 0;
+#if !defined(__APPLE__) && !defined(_MSC_VER)
+ assert (data_fd < FD_SETSIZE);
+ if (have_pipe_fd)
+ assert (pipe_fd < FD_SETSIZE);
+#endif
while (data_fd == m_fd_recv)
{
const int nfds = std::max<int>(data_fd, 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)
@@ -766,9 +773,13 @@ ConnectionFileDescriptor::BytesAvailable
// 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
- FD_SET (data_fd, read_fds.data());
+#else
+ fd_set read_fds;
+ FD_ZERO (&read_fds);
+#endif
+ FD_SET (data_fd, FD_SET_DATA(read_fds));
if (have_pipe_fd)
- FD_SET (pipe_fd, read_fds.data());
+ FD_SET (pipe_fd, FD_SET_DATA(read_fds));
Error error;
@@ -784,7 +795,7 @@ ConnectionFileDescriptor::BytesAvailable
static_cast<void*>(tv_ptr));
}
- const int num_set_fds = ::select (nfds, read_fds.data(), NULL, NULL, 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
@@ -833,11 +844,9 @@ ConnectionFileDescriptor::BytesAvailable
}
else if (num_set_fds > 0)
{
- // FD_ISSET is happy to deal with a something larger than
- // a single fd_set.
- if (FD_ISSET(data_fd, read_fds.data()))
+ if (FD_ISSET(data_fd, FD_SET_DATA(read_fds)))
return eConnectionStatusSuccess;
- if (have_pipe_fd && FD_ISSET(pipe_fd, read_fds.data()))
+ if (have_pipe_fd && FD_ISSET(pipe_fd, FD_SET_DATA(read_fds)))
{
// We got a command to exit. Read the data from that pipe:
char buffer[16];
@@ -869,174 +878,6 @@ ConnectionFileDescriptor::BytesAvailable
error_ptr->SetErrorString("not connected");
return eConnectionStatusLostConnection;
}
-
-#else
-
-// This ConnectionFileDescriptor::BytesAvailable() uses select().
-//
-// PROS:
-// - select is consistent across most unix platforms
-// CONS:
-// - only supports file descriptors up to FD_SETSIZE. This implementation
-// will assert if it runs into that hard limit to let users know that
-// another ConnectionFileDescriptor::BytesAvailable() should be used
-// or a new version of ConnectionFileDescriptor::BytesAvailable() should
-// be written for the system that is running into the limitations. MacOSX
-// uses kqueues, and there is a poll() based implementation below.
-
-ConnectionStatus
-ConnectionFileDescriptor::BytesAvailable (uint32_t timeout_usec, Error *error_ptr)
-{
- // Don't need to take the mutex here separately since we are only called from Read. If we
- // ever get used more generally we will need to lock here as well.
-
- Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
- 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 = NULL;
- }
- 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
- // and cause problems in the loop below where like in FS_SET()
- const int data_fd = m_fd_recv;
- const int pipe_fd = m_pipe_read;
-
- if (data_fd >= 0)
- {
- // If this assert fires off on MacOSX, we will need to switch to using
- // libdispatch to read from file descriptors because poll() is causing
- // kernel panics and if we exceed FD_SETSIZE we will have no choice...
-#ifndef _MSC_VER
- assert (data_fd < FD_SETSIZE);
-#endif
-
- const bool have_pipe_fd = pipe_fd >= 0;
-
- if (have_pipe_fd)
- {
- assert (pipe_fd < FD_SETSIZE);
- }
-
- while (data_fd == m_fd_recv)
- {
- fd_set read_fds;
- FD_ZERO (&read_fds);
- FD_SET (data_fd, &read_fds);
- if (have_pipe_fd)
- FD_SET (pipe_fd, &read_fds);
-
- const int nfds = std::max<int>(data_fd, pipe_fd) + 1;
-
- 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, data_fd, 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, data_fd,
- static_cast<void*>(tv_ptr));
- }
-
- const int num_set_fds = ::select (nfds, &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, data_fd, 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, data_fd,
- static_cast<void*>(tv_ptr), num_set_fds,
- error.AsCString());
- }
-
- if (error_ptr)
- *error_ptr = error;
-
- if (error.Fail())
- {
- switch (error.GetError())
- {
- case EBADF: // One of the descriptor sets specified an invalid descriptor.
- return eConnectionStatusLostConnection;
-
- case EINVAL: // The specified time limit is invalid. One of its components is negative or too large.
- default: // Other unknown error
- return eConnectionStatusError;
-
- case EAGAIN: // The kernel was (perhaps temporarily) unable to
- // allocate the requested number of file descriptors,
- // or we have non-blocking IO
- case EINTR: // A signal was delivered before the time limit
- // expired and before any of the selected events
- // occurred.
- break; // Lets keep reading to until we timeout
- }
- }
- else if (num_set_fds == 0)
- {
- return eConnectionStatusTimedOut;
- }
- else if (num_set_fds > 0)
- {
- if (FD_ISSET(data_fd, &read_fds))
- return eConnectionStatusSuccess;
- if (have_pipe_fd && FD_ISSET(pipe_fd, &read_fds))
- {
- // We got a command to exit. Read the data from that pipe:
- char buffer[16];
- ssize_t bytes_read;
-
- do
- {
- bytes_read = ::read (pipe_fd, buffer, sizeof(buffer));
- } while (bytes_read < 0 && errno == EINTR);
- assert (bytes_read == 1 && buffer[0] == 'q');
-
- if (log)
- log->Printf("%p ConnectionFileDescriptor::BytesAvailable() got data: %*s from the command channel.",
- static_cast<void*>(this),
- static_cast<int>(bytes_read), buffer);
-
- return eConnectionStatusEndOfFile;
- }
- }
- }
- }
-
- if (error_ptr)
- error_ptr->SetErrorString("not connected");
- return eConnectionStatusLostConnection;
-}
-
-#endif
-
#if 0
#include <poll.h>
More information about the lldb-commits
mailing list