1317692Sdim//===-- MainLoop.cpp --------------------------------------------*- C++ -*-===// 2317692Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6317692Sdim// 7317692Sdim//===----------------------------------------------------------------------===// 8317692Sdim 9317692Sdim#include "llvm/Config/llvm-config.h" 10360784Sdim#include "lldb/Host/Config.h" 11317692Sdim 12317692Sdim#include "lldb/Host/MainLoop.h" 13321238Sdim#include "lldb/Host/PosixApi.h" 14318384Sdim#include "lldb/Utility/Status.h" 15317692Sdim#include <algorithm> 16317692Sdim#include <cassert> 17317692Sdim#include <cerrno> 18317692Sdim#include <csignal> 19318384Sdim#include <time.h> 20317692Sdim#include <vector> 21317692Sdim 22317969Sdim// Multiplexing is implemented using kqueue on systems that support it (BSD 23317969Sdim// variants including OSX). On linux we use ppoll, while android uses pselect 24317969Sdim// (ppoll is present but not implemented properly). On windows we use WSApoll 25317969Sdim// (which does not support signals). 26317969Sdim 27317692Sdim#if HAVE_SYS_EVENT_H 28317692Sdim#include <sys/event.h> 29341825Sdim#elif defined(_WIN32) 30317692Sdim#include <winsock2.h> 31327952Sdim#elif defined(__ANDROID__) 32327952Sdim#include <sys/syscall.h> 33317692Sdim#else 34317692Sdim#include <poll.h> 35317692Sdim#endif 36317692Sdim 37341825Sdim#ifdef _WIN32 38317692Sdim#define POLL WSAPoll 39317692Sdim#else 40317692Sdim#define POLL poll 41317692Sdim#endif 42317692Sdim 43317692Sdim#if SIGNAL_POLLING_UNSUPPORTED 44341825Sdim#ifdef _WIN32 45317692Sdimtypedef int sigset_t; 46317692Sdimtypedef int siginfo_t; 47317692Sdim#endif 48317692Sdim 49317692Sdimint ppoll(struct pollfd *fds, size_t nfds, const struct timespec *timeout_ts, 50317692Sdim const sigset_t *) { 51317692Sdim int timeout = 52317692Sdim (timeout_ts == nullptr) 53317692Sdim ? -1 54317692Sdim : (timeout_ts->tv_sec * 1000 + timeout_ts->tv_nsec / 1000000); 55317692Sdim return POLL(fds, nfds, timeout); 56317692Sdim} 57317692Sdim 58317692Sdim#endif 59317692Sdim 60317692Sdimusing namespace lldb; 61317692Sdimusing namespace lldb_private; 62317692Sdim 63317692Sdimstatic sig_atomic_t g_signal_flags[NSIG]; 64317692Sdim 65353358Sdim#ifndef SIGNAL_POLLING_UNSUPPORTED 66317692Sdimstatic void SignalHandler(int signo, siginfo_t *info, void *) { 67317692Sdim assert(signo < NSIG); 68317692Sdim g_signal_flags[signo] = 1; 69317692Sdim} 70353358Sdim#endif 71317692Sdim 72317692Sdimclass MainLoop::RunImpl { 73317692Sdimpublic: 74317969Sdim RunImpl(MainLoop &loop); 75317969Sdim ~RunImpl() = default; 76317692Sdim 77318384Sdim Status Poll(); 78317969Sdim void ProcessEvents(); 79317692Sdim 80317692Sdimprivate: 81317692Sdim MainLoop &loop; 82317692Sdim 83317692Sdim#if HAVE_SYS_EVENT_H 84317692Sdim std::vector<struct kevent> in_events; 85317692Sdim struct kevent out_events[4]; 86317692Sdim int num_events = -1; 87317692Sdim 88317692Sdim#else 89327952Sdim#ifdef __ANDROID__ 90317692Sdim fd_set read_fd_set; 91317692Sdim#else 92317692Sdim std::vector<struct pollfd> read_fds; 93317692Sdim#endif 94317692Sdim 95317692Sdim sigset_t get_sigmask(); 96317692Sdim#endif 97317692Sdim}; 98317692Sdim 99317692Sdim#if HAVE_SYS_EVENT_H 100317969SdimMainLoop::RunImpl::RunImpl(MainLoop &loop) : loop(loop) { 101317969Sdim in_events.reserve(loop.m_read_fds.size()); 102317692Sdim} 103317692Sdim 104318384SdimStatus MainLoop::RunImpl::Poll() { 105317969Sdim in_events.resize(loop.m_read_fds.size()); 106317692Sdim unsigned i = 0; 107317692Sdim for (auto &fd : loop.m_read_fds) 108317692Sdim EV_SET(&in_events[i++], fd.first, EVFILT_READ, EV_ADD, 0, 0, 0); 109317692Sdim 110317969Sdim num_events = kevent(loop.m_kqueue, in_events.data(), in_events.size(), 111317969Sdim out_events, llvm::array_lengthof(out_events), nullptr); 112317692Sdim 113344779Sdim if (num_events < 0) { 114344779Sdim if (errno == EINTR) { 115344779Sdim // in case of EINTR, let the main loop run one iteration 116344779Sdim // we need to zero num_events to avoid assertions failing 117344779Sdim num_events = 0; 118344779Sdim } else 119344779Sdim return Status(errno, eErrorTypePOSIX); 120344779Sdim } 121318384Sdim return Status(); 122317692Sdim} 123317692Sdim 124317969Sdimvoid MainLoop::RunImpl::ProcessEvents() { 125317692Sdim assert(num_events >= 0); 126317692Sdim for (int i = 0; i < num_events; ++i) { 127317692Sdim if (loop.m_terminate_request) 128317692Sdim return; 129317969Sdim switch (out_events[i].filter) { 130317969Sdim case EVFILT_READ: 131317969Sdim loop.ProcessReadObject(out_events[i].ident); 132317969Sdim break; 133317969Sdim case EVFILT_SIGNAL: 134317969Sdim loop.ProcessSignal(out_events[i].ident); 135317969Sdim break; 136317969Sdim default: 137317969Sdim llvm_unreachable("Unknown event"); 138317969Sdim } 139317692Sdim } 140317692Sdim} 141317692Sdim#else 142317969SdimMainLoop::RunImpl::RunImpl(MainLoop &loop) : loop(loop) { 143327952Sdim#ifndef __ANDROID__ 144317969Sdim read_fds.reserve(loop.m_read_fds.size()); 145317969Sdim#endif 146317692Sdim} 147317692Sdim 148317692Sdimsigset_t MainLoop::RunImpl::get_sigmask() { 149353358Sdim sigset_t sigmask; 150353358Sdim#if defined(_WIN32) 151353358Sdim sigmask = 0; 152353358Sdim#elif SIGNAL_POLLING_UNSUPPORTED 153353358Sdim sigemptyset(&sigmask); 154317692Sdim#else 155317692Sdim int ret = pthread_sigmask(SIG_SETMASK, nullptr, &sigmask); 156317692Sdim assert(ret == 0); 157317692Sdim (void) ret; 158317692Sdim 159317969Sdim for (const auto &sig : loop.m_signals) 160317692Sdim sigdelset(&sigmask, sig.first); 161353358Sdim#endif 162317692Sdim return sigmask; 163317692Sdim} 164317692Sdim 165327952Sdim#ifdef __ANDROID__ 166318384SdimStatus MainLoop::RunImpl::Poll() { 167327952Sdim // ppoll(2) is not supported on older all android versions. Also, older 168327952Sdim // versions android (API <= 19) implemented pselect in a non-atomic way, as a 169327952Sdim // combination of pthread_sigmask and select. This is not sufficient for us, 170327952Sdim // as we rely on the atomicity to correctly implement signal polling, so we 171327952Sdim // call the underlying syscall ourselves. 172327952Sdim 173317692Sdim FD_ZERO(&read_fd_set); 174317692Sdim int nfds = 0; 175317692Sdim for (const auto &fd : loop.m_read_fds) { 176317692Sdim FD_SET(fd.first, &read_fd_set); 177317692Sdim nfds = std::max(nfds, fd.first + 1); 178317692Sdim } 179317692Sdim 180327952Sdim union { 181327952Sdim sigset_t set; 182327952Sdim uint64_t pad; 183327952Sdim } kernel_sigset; 184327952Sdim memset(&kernel_sigset, 0, sizeof(kernel_sigset)); 185327952Sdim kernel_sigset.set = get_sigmask(); 186327952Sdim 187327952Sdim struct { 188327952Sdim void *sigset_ptr; 189327952Sdim size_t sigset_len; 190327952Sdim } extra_data = {&kernel_sigset, sizeof(kernel_sigset)}; 191327952Sdim if (syscall(__NR_pselect6, nfds, &read_fd_set, nullptr, nullptr, nullptr, 192327952Sdim &extra_data) == -1 && 193317692Sdim errno != EINTR) 194318384Sdim return Status(errno, eErrorTypePOSIX); 195317692Sdim 196318384Sdim return Status(); 197317692Sdim} 198317692Sdim#else 199318384SdimStatus MainLoop::RunImpl::Poll() { 200317692Sdim read_fds.clear(); 201317692Sdim 202317692Sdim sigset_t sigmask = get_sigmask(); 203317692Sdim 204317692Sdim for (const auto &fd : loop.m_read_fds) { 205317692Sdim struct pollfd pfd; 206317692Sdim pfd.fd = fd.first; 207317692Sdim pfd.events = POLLIN; 208317692Sdim pfd.revents = 0; 209317692Sdim read_fds.push_back(pfd); 210317692Sdim } 211317692Sdim 212317692Sdim if (ppoll(read_fds.data(), read_fds.size(), nullptr, &sigmask) == -1 && 213317692Sdim errno != EINTR) 214318384Sdim return Status(errno, eErrorTypePOSIX); 215317692Sdim 216318384Sdim return Status(); 217317692Sdim} 218317969Sdim#endif 219317692Sdim 220317969Sdimvoid MainLoop::RunImpl::ProcessEvents() { 221327952Sdim#ifdef __ANDROID__ 222341825Sdim // Collect first all readable file descriptors into a separate vector and 223341825Sdim // then iterate over it to invoke callbacks. Iterating directly over 224320970Sdim // loop.m_read_fds is not possible because the callbacks can modify the 225320970Sdim // container which could invalidate the iterator. 226320970Sdim std::vector<IOObject::WaitableHandle> fds; 227320970Sdim for (const auto &fd : loop.m_read_fds) 228320970Sdim if (FD_ISSET(fd.first, &read_fd_set)) 229320970Sdim fds.push_back(fd.first); 230320970Sdim 231320970Sdim for (const auto &handle : fds) { 232317969Sdim#else 233317692Sdim for (const auto &fd : read_fds) { 234327952Sdim if ((fd.revents & (POLLIN | POLLHUP)) == 0) 235317692Sdim continue; 236317969Sdim IOObject::WaitableHandle handle = fd.fd; 237317969Sdim#endif 238317692Sdim if (loop.m_terminate_request) 239317692Sdim return; 240317969Sdim 241317969Sdim loop.ProcessReadObject(handle); 242317692Sdim } 243317692Sdim 244320970Sdim std::vector<int> signals; 245320970Sdim for (const auto &entry : loop.m_signals) 246320970Sdim if (g_signal_flags[entry.first] != 0) 247320970Sdim signals.push_back(entry.first); 248320970Sdim 249320970Sdim for (const auto &signal : signals) { 250317692Sdim if (loop.m_terminate_request) 251317692Sdim return; 252320970Sdim g_signal_flags[signal] = 0; 253320970Sdim loop.ProcessSignal(signal); 254317692Sdim } 255317692Sdim} 256317692Sdim#endif 257317692Sdim 258317969SdimMainLoop::MainLoop() { 259317969Sdim#if HAVE_SYS_EVENT_H 260317969Sdim m_kqueue = kqueue(); 261317969Sdim assert(m_kqueue >= 0); 262317969Sdim#endif 263317969Sdim} 264317692SdimMainLoop::~MainLoop() { 265317969Sdim#if HAVE_SYS_EVENT_H 266317969Sdim close(m_kqueue); 267317969Sdim#endif 268317692Sdim assert(m_read_fds.size() == 0); 269317692Sdim assert(m_signals.size() == 0); 270317692Sdim} 271317692Sdim 272318384SdimMainLoop::ReadHandleUP MainLoop::RegisterReadObject(const IOObjectSP &object_sp, 273318384Sdim const Callback &callback, 274318384Sdim Status &error) { 275341825Sdim#ifdef _WIN32 276317692Sdim if (object_sp->GetFdType() != IOObject:: eFDTypeSocket) { 277317692Sdim error.SetErrorString("MainLoop: non-socket types unsupported on Windows"); 278317692Sdim return nullptr; 279317692Sdim } 280317692Sdim#endif 281317692Sdim if (!object_sp || !object_sp->IsValid()) { 282317692Sdim error.SetErrorString("IO object is not valid."); 283317692Sdim return nullptr; 284317692Sdim } 285317692Sdim 286317692Sdim const bool inserted = 287317692Sdim m_read_fds.insert({object_sp->GetWaitableHandle(), callback}).second; 288317692Sdim if (!inserted) { 289317692Sdim error.SetErrorStringWithFormat("File descriptor %d already monitored.", 290317692Sdim object_sp->GetWaitableHandle()); 291317692Sdim return nullptr; 292317692Sdim } 293317692Sdim 294317692Sdim return CreateReadHandle(object_sp); 295317692Sdim} 296317692Sdim 297317692Sdim// We shall block the signal, then install the signal handler. The signal will 298341825Sdim// be unblocked in the Run() function to check for signal delivery. 299317692SdimMainLoop::SignalHandleUP 300318384SdimMainLoop::RegisterSignal(int signo, const Callback &callback, Status &error) { 301317692Sdim#ifdef SIGNAL_POLLING_UNSUPPORTED 302317692Sdim error.SetErrorString("Signal polling is not supported on this platform."); 303317692Sdim return nullptr; 304317692Sdim#else 305317692Sdim if (m_signals.find(signo) != m_signals.end()) { 306317692Sdim error.SetErrorStringWithFormat("Signal %d already monitored.", signo); 307317692Sdim return nullptr; 308317692Sdim } 309317692Sdim 310317692Sdim SignalInfo info; 311317692Sdim info.callback = callback; 312317692Sdim struct sigaction new_action; 313317692Sdim new_action.sa_sigaction = &SignalHandler; 314317692Sdim new_action.sa_flags = SA_SIGINFO; 315317692Sdim sigemptyset(&new_action.sa_mask); 316317692Sdim sigaddset(&new_action.sa_mask, signo); 317317692Sdim sigset_t old_set; 318317692Sdim 319317969Sdim g_signal_flags[signo] = 0; 320317969Sdim 321317969Sdim // Even if using kqueue, the signal handler will still be invoked, so it's 322344779Sdim // important to replace it with our "benign" handler. 323317969Sdim int ret = sigaction(signo, &new_action, &info.old_action); 324360784Sdim (void)ret; 325317969Sdim assert(ret == 0 && "sigaction failed"); 326317969Sdim 327317969Sdim#if HAVE_SYS_EVENT_H 328317969Sdim struct kevent ev; 329317969Sdim EV_SET(&ev, signo, EVFILT_SIGNAL, EV_ADD, 0, 0, 0); 330317969Sdim ret = kevent(m_kqueue, &ev, 1, nullptr, 0, nullptr); 331317969Sdim assert(ret == 0); 332317969Sdim#endif 333317969Sdim 334341825Sdim // If we're using kqueue, the signal needs to be unblocked in order to 335344779Sdim // receive it. If using pselect/ppoll, we need to block it, and later unblock 336341825Sdim // it as a part of the system call. 337317969Sdim ret = pthread_sigmask(HAVE_SYS_EVENT_H ? SIG_UNBLOCK : SIG_BLOCK, 338317969Sdim &new_action.sa_mask, &old_set); 339317969Sdim assert(ret == 0 && "pthread_sigmask failed"); 340317692Sdim info.was_blocked = sigismember(&old_set, signo); 341317692Sdim m_signals.insert({signo, info}); 342317692Sdim 343317692Sdim return SignalHandleUP(new SignalHandle(*this, signo)); 344317692Sdim#endif 345317692Sdim} 346317692Sdim 347317692Sdimvoid MainLoop::UnregisterReadObject(IOObject::WaitableHandle handle) { 348317692Sdim bool erased = m_read_fds.erase(handle); 349317692Sdim UNUSED_IF_ASSERT_DISABLED(erased); 350317692Sdim assert(erased); 351317692Sdim} 352317692Sdim 353317692Sdimvoid MainLoop::UnregisterSignal(int signo) { 354317692Sdim#if SIGNAL_POLLING_UNSUPPORTED 355318384Sdim Status("Signal polling is not supported on this platform."); 356317692Sdim#else 357317692Sdim auto it = m_signals.find(signo); 358317692Sdim assert(it != m_signals.end()); 359317692Sdim 360317692Sdim sigaction(signo, &it->second.old_action, nullptr); 361317692Sdim 362317692Sdim sigset_t set; 363317692Sdim sigemptyset(&set); 364317692Sdim sigaddset(&set, signo); 365317969Sdim int ret = pthread_sigmask(it->second.was_blocked ? SIG_BLOCK : SIG_UNBLOCK, 366317969Sdim &set, nullptr); 367317969Sdim assert(ret == 0); 368317969Sdim (void)ret; 369317692Sdim 370317969Sdim#if HAVE_SYS_EVENT_H 371317969Sdim struct kevent ev; 372317969Sdim EV_SET(&ev, signo, EVFILT_SIGNAL, EV_DELETE, 0, 0, 0); 373317969Sdim ret = kevent(m_kqueue, &ev, 1, nullptr, 0, nullptr); 374317969Sdim assert(ret == 0); 375317969Sdim#endif 376317969Sdim 377317692Sdim m_signals.erase(it); 378317692Sdim#endif 379317692Sdim} 380317692Sdim 381318384SdimStatus MainLoop::Run() { 382317692Sdim m_terminate_request = false; 383318384Sdim 384318384Sdim Status error; 385317969Sdim RunImpl impl(*this); 386317692Sdim 387317692Sdim // run until termination or until we run out of things to listen to 388317692Sdim while (!m_terminate_request && (!m_read_fds.empty() || !m_signals.empty())) { 389317692Sdim 390317969Sdim error = impl.Poll(); 391317692Sdim if (error.Fail()) 392317692Sdim return error; 393317692Sdim 394317969Sdim impl.ProcessEvents(); 395317692Sdim } 396318384Sdim return Status(); 397317692Sdim} 398317969Sdim 399317969Sdimvoid MainLoop::ProcessSignal(int signo) { 400317969Sdim auto it = m_signals.find(signo); 401317969Sdim if (it != m_signals.end()) 402317969Sdim it->second.callback(*this); // Do the work 403317969Sdim} 404317969Sdim 405317969Sdimvoid MainLoop::ProcessReadObject(IOObject::WaitableHandle handle) { 406317969Sdim auto it = m_read_fds.find(handle); 407317969Sdim if (it != m_read_fds.end()) 408317969Sdim it->second(*this); // Do the work 409317969Sdim} 410