10#include "lldb/Host/Config.h"
13#include "llvm/Config/llvm-config.h"
14#include "llvm/Support/Errno.h"
29#elif defined(__ANDROID__)
30#include <sys/syscall.h>
57 std::vector<struct kevent> in_events;
58 struct kevent out_events[4];
81 EV_SET(&in_events[i++], fd.first, EVFILT_READ, EV_ADD, 0, 0, 0);
83 num_events = kevent(loop.m_kqueue, in_events.data(), in_events.size(),
84 out_events, std::size(out_events),
nullptr);
98 assert(num_events >= 0);
99 for (
int i = 0; i < num_events; ++i) {
102 switch (out_events[i].filter) {
110 llvm_unreachable(
"Unknown event");
123 int ret = pthread_sigmask(SIG_SETMASK,
nullptr, &sigmask);
128 sigdelset(&sigmask, sig.first);
140 FD_ZERO(&read_fd_set);
143 FD_SET(fd.first, &read_fd_set);
144 nfds = std::max(nfds, fd.first + 1);
151 memset(&kernel_sigset, 0,
sizeof(kernel_sigset));
152 kernel_sigset.set = get_sigmask();
157 } extra_data = {&kernel_sigset,
sizeof(kernel_sigset)};
158 if (syscall(__NR_pselect6, nfds, &read_fd_set,
nullptr,
nullptr,
nullptr,
159 &extra_data) == -1) {
163 FD_ZERO(&read_fd_set);
172 sigset_t sigmask = get_sigmask();
179 read_fds.push_back(pfd);
182 if (ppoll(read_fds.data(), read_fds.size(),
nullptr, &sigmask) == -1 &&
196 std::vector<IOObject::WaitableHandle> fds;
198 if (FD_ISSET(fd.first, &read_fd_set))
199 fds.push_back(fd.first);
201 for (
const auto &handle : fds) {
203 for (
const auto &fd : read_fds) {
204 if ((fd.revents & (POLLIN | POLLHUP)) == 0)
214 std::vector<int> signals;
217 signals.push_back(entry.first);
219 for (
const auto &signal : signals) {
230 assert(
error.Success());
234 ssize_t bytes_read = llvm::sys::RetryAfterSignal(
235 -1, ::read, trigger_pipe_fd, &c, 1);
236 assert(bytes_read == 1);
243 assert(m_kqueue >= 0);
260 if (!object_sp || !object_sp->IsValid()) {
261 error.SetErrorString(
"IO object is not valid.");
265 const bool inserted =
266 m_read_fds.insert({object_sp->GetWaitableHandle(), callback}).second;
268 error.SetErrorStringWithFormat(
"File descriptor %d already monitored.",
269 object_sp->GetWaitableHandle());
283 auto callback_it = signal_it->second.callbacks.insert(
284 signal_it->second.callbacks.end(), callback);
290 struct sigaction new_action;
292 new_action.sa_flags = SA_SIGINFO;
293 sigemptyset(&new_action.sa_mask);
294 sigaddset(&new_action.sa_mask, signo);
301 int ret = sigaction(signo, &new_action, &info.
old_action);
303 assert(ret == 0 &&
"sigaction failed");
307 EV_SET(&ev, signo, EVFILT_SIGNAL, EV_ADD, 0, 0, 0);
308 ret = kevent(m_kqueue, &ev, 1,
nullptr, 0,
nullptr);
315 ret = pthread_sigmask(HAVE_SYS_EVENT_H ? SIG_UNBLOCK : SIG_BLOCK,
316 &new_action.sa_mask, &old_set);
317 assert(ret == 0 &&
"pthread_sigmask failed");
319 auto insert_ret =
m_signals.insert({signo, info});
322 *
this, signo, insert_ret.first->second.callbacks.begin()));
332 int signo, std::list<Callback>::iterator callback_it) {
336 it->second.callbacks.erase(callback_it);
338 if (!it->second.callbacks.empty())
341 sigaction(signo, &it->second.old_action,
nullptr);
345 sigaddset(&set, signo);
346 int ret = pthread_sigmask(it->second.was_blocked ? SIG_BLOCK : SIG_UNBLOCK,
353 EV_SET(&ev, signo, EVFILT_SIGNAL, EV_DELETE, 0, 0, 0);
354 ret = kevent(m_kqueue, &ev, 1,
nullptr, 0,
nullptr);
394 llvm::SmallVector<Callback, 4> callbacks_to_run{
395 it->second.callbacks.begin(), it->second.callbacks.end()};
396 for (
auto &x : callbacks_to_run)
406 size_t bytes_written;
408 assert(
error.Success());
410 assert(bytes_written == 1);
static llvm::raw_ostream & error(Stream &strm)
static void SignalHandler(int signo, siginfo_t *info, void *)
static sig_atomic_t g_signal_flags[NSIG]
std::vector< struct pollfd > read_fds
RunImpl(MainLoopPosix &loop)
std::unique_ptr< ReadHandle > ReadHandleUP
ReadHandleUP CreateReadHandle(const lldb::IOObjectSP &object_sp)
std::function< void(MainLoopBase &)> Callback
void ProcessPendingCallbacks()
void TriggerPendingCallbacks() override
SignalHandleUP RegisterSignal(int signo, const Callback &callback, Status &error)
void UnregisterReadObject(IOObject::WaitableHandle handle) override
ReadHandleUP RegisterReadObject(const lldb::IOObjectSP &object_sp, const Callback &callback, Status &error) override
void ProcessReadObject(IOObject::WaitableHandle handle)
llvm::DenseMap< int, SignalInfo > m_signals
~MainLoopPosix() override
std::atomic< bool > m_triggering
llvm::DenseMap< IOObject::WaitableHandle, Callback > m_read_fds
void ProcessSignal(int signo)
std::unique_ptr< SignalHandle > SignalHandleUP
void UnregisterSignal(int signo, std::list< Callback >::iterator callback_it)
Status Write(const void *buf, size_t size, size_t &bytes_written)
int GetReadFileDescriptor() const override
Status CreateNew(bool child_process_inherit) override
#define UNUSED_IF_ASSERT_DISABLED(x)
A class that represents a running process on the host machine.
std::shared_ptr< lldb_private::IOObject > IOObjectSP
@ eErrorTypePOSIX
POSIX error codes.
std::list< Callback > callbacks
struct sigaction old_action