diff options
| -rw-r--r-- | lldb/include/lldb/Host/MainLoop.h | 6 | ||||
| -rw-r--r-- | lldb/source/Host/common/MainLoop.cpp | 32 |
2 files changed, 27 insertions, 11 deletions
diff --git a/lldb/include/lldb/Host/MainLoop.h b/lldb/include/lldb/Host/MainLoop.h index eda01c02a20..c59a5aa5b0e 100644 --- a/lldb/include/lldb/Host/MainLoop.h +++ b/lldb/include/lldb/Host/MainLoop.h @@ -15,11 +15,7 @@ #include "llvm/ADT/DenseMap.h" #include <csignal> -#ifdef __ANDROID__ -#define FORCE_PSELECT -#endif - -#if !HAVE_PPOLL && !HAVE_SYS_EVENT_H && !defined(FORCE_PSELECT) +#if !HAVE_PPOLL && !HAVE_SYS_EVENT_H && !defined(__ANDROID__) #define SIGNAL_POLLING_UNSUPPORTED 1 #endif diff --git a/lldb/source/Host/common/MainLoop.cpp b/lldb/source/Host/common/MainLoop.cpp index e48882b274e..4f7052a7a22 100644 --- a/lldb/source/Host/common/MainLoop.cpp +++ b/lldb/source/Host/common/MainLoop.cpp @@ -18,6 +18,7 @@ #include <csignal> #include <time.h> #include <vector> +#include <sys/syscall.h> // Multiplexing is implemented using kqueue on systems that support it (BSD // variants including OSX). On linux we use ppoll, while android uses pselect @@ -28,6 +29,8 @@ #include <sys/event.h> #elif defined(LLVM_ON_WIN32) #include <winsock2.h> +#elif defined(__ANDROID__) +#include <sys/syscall.h> #else #include <poll.h> #endif @@ -82,7 +85,7 @@ private: int num_events = -1; #else -#ifdef FORCE_PSELECT +#ifdef __ANDROID__ fd_set read_fd_set; #else std::vector<struct pollfd> read_fds; @@ -130,7 +133,7 @@ void MainLoop::RunImpl::ProcessEvents() { } #else MainLoop::RunImpl::RunImpl(MainLoop &loop) : loop(loop) { -#ifndef FORCE_PSELECT +#ifndef __ANDROID__ read_fds.reserve(loop.m_read_fds.size()); #endif } @@ -150,8 +153,14 @@ sigset_t MainLoop::RunImpl::get_sigmask() { #endif } -#ifdef FORCE_PSELECT +#ifdef __ANDROID__ Status MainLoop::RunImpl::Poll() { + // ppoll(2) is not supported on older all android versions. Also, older + // versions android (API <= 19) implemented pselect in a non-atomic way, as a + // combination of pthread_sigmask and select. This is not sufficient for us, + // as we rely on the atomicity to correctly implement signal polling, so we + // call the underlying syscall ourselves. + FD_ZERO(&read_fd_set); int nfds = 0; for (const auto &fd : loop.m_read_fds) { @@ -159,8 +168,19 @@ Status MainLoop::RunImpl::Poll() { nfds = std::max(nfds, fd.first + 1); } - sigset_t sigmask = get_sigmask(); - if (pselect(nfds, &read_fd_set, nullptr, nullptr, nullptr, &sigmask) == -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 && errno != EINTR) return Status(errno, eErrorTypePOSIX); @@ -189,7 +209,7 @@ Status MainLoop::RunImpl::Poll() { #endif void MainLoop::RunImpl::ProcessEvents() { -#ifdef FORCE_PSELECT +#ifdef __ANDROID__ // Collect first all readable file descriptors into a separate vector and then // iterate over it to invoke callbacks. Iterating directly over // loop.m_read_fds is not possible because the callbacks can modify the |

