summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/Host/MainLoop.h6
-rw-r--r--lldb/source/Host/common/MainLoop.cpp32
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
OpenPOWER on IntegriCloud