13#define _DARWIN_UNLIMITED_SELECT
22#include "llvm/ADT/DenseMap.h"
35#include <sys/select.h>
40 : m_fd_map(), m_end_time()
45 using namespace std::chrono;
46 m_end_time = steady_clock::time_point(steady_clock::now() + timeout);
64 return pos->second.read_is_set;
72 return pos->second.write_is_set;
80 return pos->second.error_is_set;
90 vold = std::max(*vold, vnew);
101 "Too many file descriptors for select()");
104 std::optional<lldb::socket_t> max_read_fd;
105 std::optional<lldb::socket_t> max_write_fd;
106 std::optional<lldb::socket_t> max_error_fd;
107 std::optional<lldb::socket_t> max_fd;
109 pair.second.PrepareForSelect();
111#if !defined(__APPLE__) && !defined(_WIN32)
112 lldbassert(fd <
static_cast<int>(FD_SETSIZE));
113 if (fd >=
static_cast<int>(FD_SETSIZE)) {
115 "%i is too large for select()", fd);
119 if (pair.second.read_set)
121 if (pair.second.write_set)
123 if (pair.second.error_set)
132 const unsigned nfds =
static_cast<unsigned>(*max_fd) + 1;
133 fd_set *read_fdset_ptr =
nullptr;
134 fd_set *write_fdset_ptr =
nullptr;
135 fd_set *error_fdset_ptr =
nullptr;
137#if defined(__APPLE__)
138 llvm::SmallVector<fd_set, 1> read_fdset;
139 llvm::SmallVector<fd_set, 1> write_fdset;
140 llvm::SmallVector<fd_set, 1> error_fdset;
142 if (max_read_fd.has_value()) {
143 read_fdset.resize((nfds / FD_SETSIZE) + 1);
144 read_fdset_ptr = read_fdset.data();
146 if (max_write_fd.has_value()) {
147 write_fdset.resize((nfds / FD_SETSIZE) + 1);
148 write_fdset_ptr = write_fdset.data();
150 if (max_error_fd.has_value()) {
151 error_fdset.resize((nfds / FD_SETSIZE) + 1);
152 error_fdset_ptr = error_fdset.data();
154 for (
auto &fd_set : read_fdset)
156 for (
auto &fd_set : write_fdset)
158 for (
auto &fd_set : error_fdset)
166 FD_ZERO(&read_fdset);
167 read_fdset_ptr = &read_fdset;
170 FD_ZERO(&write_fdset);
171 write_fdset_ptr = &write_fdset;
174 FD_ZERO(&error_fdset);
175 error_fdset_ptr = &error_fdset;
182 if (pair.second.read_set)
183 FD_SET(fd, read_fdset_ptr);
185 if (pair.second.write_set)
186 FD_SET(fd, write_fdset_ptr);
188 if (pair.second.error_set)
189 FD_SET(fd, error_fdset_ptr);
193 struct timeval *tv_ptr =
nullptr;
194 struct timeval tv = {0, 0};
197 using namespace std::chrono;
201 const auto remaining_dur =
202 duration_cast<microseconds>(*
m_end_time - steady_clock::now());
203 if (remaining_dur.count() > 0) {
205 const auto dur_secs = duration_cast<seconds>(remaining_dur);
206 const auto dur_usecs = remaining_dur % seconds(1);
207 tv.tv_sec = dur_secs.count();
208 tv.tv_usec = dur_usecs.count();
215 const int num_set_fds = ::select(nfds, read_fdset_ptr, write_fdset_ptr,
216 error_fdset_ptr, tv_ptr);
217 if (num_set_fds < 0) {
220 if (
error.GetError() == EINTR) {
225 }
else if (num_set_fds == 0) {
235 const int fd = pair.first;
237 if (pair.second.read_set) {
238 if (FD_ISSET(fd, read_fdset_ptr))
239 pair.second.read_is_set =
true;
241 if (pair.second.write_set) {
242 if (FD_ISSET(fd, write_fdset_ptr))
243 pair.second.write_is_set =
true;
245 if (pair.second.error_set) {
246 if (FD_ISSET(fd, error_fdset_ptr))
247 pair.second.error_is_set =
true;
static llvm::raw_ostream & error(Stream &strm)
static void updateMaxFd(std::optional< lldb::socket_t > &vold, lldb::socket_t vnew)
bool FDIsSetWrite(lldb::socket_t fd) const
lldb_private::Status Select()
void FDSetRead(lldb::socket_t fd)
bool FDIsSetError(lldb::socket_t fd) const
llvm::DenseMap< lldb::socket_t, FDInfo > m_fd_map
void SetTimeout(const std::chrono::microseconds &timeout)
std::optional< std::chrono::steady_clock::time_point > m_end_time
void FDSetError(lldb::socket_t fd)
void FDSetWrite(lldb::socket_t fd)
bool FDIsSetRead(lldb::socket_t fd) const
static Status FromErrno()
Set the current error to errno.
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
static Status FromErrorString(const char *str)
@ eErrorTypePOSIX
POSIX error codes.