#include "lldb/Host/posix/MainLoopPosix.h"
#include "lldb/Host/Config.h"
#include "lldb/Host/PosixApi.h"
#include "lldb/Utility/Status.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/Support/Errno.h"
#include <algorithm>
#include <cassert>
#include <cerrno>
#include <csignal>
#include <ctime>
#include <vector>
#if HAVE_SYS_EVENT_H
#include <sys/event.h>
#elif defined(__ANDROID__)
#include <sys/syscall.h>
#else
#include <poll.h>
#endif
usingnamespacelldb;
usingnamespacelldb_private;
static sig_atomic_t g_signal_flags[NSIG];
static void SignalHandler(int signo, siginfo_t *info, void *) { … }
class MainLoopPosix::RunImpl { … };
#if HAVE_SYS_EVENT_H
MainLoopPosix::RunImpl::RunImpl(MainLoopPosix &loop) : loop(loop) {
in_events.reserve(loop.m_read_fds.size());
}
Status MainLoopPosix::RunImpl::Poll() {
in_events.resize(loop.m_read_fds.size());
unsigned i = 0;
for (auto &fd : loop.m_read_fds)
EV_SET(&in_events[i++], fd.first, EVFILT_READ, EV_ADD, 0, 0, 0);
num_events = kevent(loop.m_kqueue, in_events.data(), in_events.size(),
out_events, std::size(out_events), nullptr);
if (num_events < 0) {
if (errno == EINTR) {
num_events = 0;
} else
return Status(errno, eErrorTypePOSIX);
}
return Status();
}
void MainLoopPosix::RunImpl::ProcessEvents() {
assert(num_events >= 0);
for (int i = 0; i < num_events; ++i) {
if (loop.m_terminate_request)
return;
switch (out_events[i].filter) {
case EVFILT_READ:
loop.ProcessReadObject(out_events[i].ident);
break;
case EVFILT_SIGNAL:
loop.ProcessSignal(out_events[i].ident);
break;
default:
llvm_unreachable("Unknown event");
}
}
}
#else
MainLoopPosix::RunImpl::RunImpl(MainLoopPosix &loop) : … { … }
sigset_t MainLoopPosix::RunImpl::get_sigmask() { … }
#ifdef __ANDROID__
Status MainLoopPosix::RunImpl::Poll() {
FD_ZERO(&read_fd_set);
int nfds = 0;
for (const auto &fd : loop.m_read_fds) {
FD_SET(fd.first, &read_fd_set);
nfds = std::max(nfds, fd.first + 1);
}
union {
sigset_t set;
uint64_t pad;
} kernel_sigset;
memset(&kernel_sigset, 0, sizeof(kernel_sigset));
kernel_sigset.set = get_sigmask();
struct {
void *sigset_ptr;
size_t sigset_len;
} extra_data = {&kernel_sigset, sizeof(kernel_sigset)};
if (syscall(__NR_pselect6, nfds, &read_fd_set, nullptr, nullptr, nullptr,
&extra_data) == -1) {
if (errno != EINTR)
return Status(errno, eErrorTypePOSIX);
else
FD_ZERO(&read_fd_set);
}
return Status();
}
#else
Status MainLoopPosix::RunImpl::Poll() { … }
#endif
void MainLoopPosix::RunImpl::ProcessEvents() { … }
#endif
MainLoopPosix::MainLoopPosix() : … { … }
MainLoopPosix::~MainLoopPosix() { … }
MainLoopPosix::ReadHandleUP
MainLoopPosix::RegisterReadObject(const IOObjectSP &object_sp,
const Callback &callback, Status &error) { … }
MainLoopPosix::SignalHandleUP
MainLoopPosix::RegisterSignal(int signo, const Callback &callback,
Status &error) { … }
void MainLoopPosix::UnregisterReadObject(IOObject::WaitableHandle handle) { … }
void MainLoopPosix::UnregisterSignal(
int signo, std::list<Callback>::iterator callback_it) { … }
Status MainLoopPosix::Run() { … }
void MainLoopPosix::ProcessReadObject(IOObject::WaitableHandle handle) { … }
void MainLoopPosix::ProcessSignal(int signo) { … }
void MainLoopPosix::TriggerPendingCallbacks() { … }