]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/lldb/source/Host/common/MainLoop.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm-project / lldb / source / Host / common / MainLoop.cpp
1 //===-- MainLoop.cpp --------------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/Config/llvm-config.h"
10
11 #include "lldb/Host/MainLoop.h"
12 #include "lldb/Host/PosixApi.h"
13 #include "lldb/Utility/Status.h"
14 #include <algorithm>
15 #include <cassert>
16 #include <cerrno>
17 #include <csignal>
18 #include <time.h>
19 #include <vector>
20
21 // Multiplexing is implemented using kqueue on systems that support it (BSD
22 // variants including OSX). On linux we use ppoll, while android uses pselect
23 // (ppoll is present but not implemented properly). On windows we use WSApoll
24 // (which does not support signals).
25
26 #if HAVE_SYS_EVENT_H
27 #include <sys/event.h>
28 #elif defined(_WIN32)
29 #include <winsock2.h>
30 #elif defined(__ANDROID__)
31 #include <sys/syscall.h>
32 #else
33 #include <poll.h>
34 #endif
35
36 #ifdef _WIN32
37 #define POLL WSAPoll
38 #else
39 #define POLL poll
40 #endif
41
42 #if SIGNAL_POLLING_UNSUPPORTED
43 #ifdef _WIN32
44 typedef int sigset_t;
45 typedef int siginfo_t;
46 #endif
47
48 int ppoll(struct pollfd *fds, size_t nfds, const struct timespec *timeout_ts,
49           const sigset_t *) {
50   int timeout =
51       (timeout_ts == nullptr)
52           ? -1
53           : (timeout_ts->tv_sec * 1000 + timeout_ts->tv_nsec / 1000000);
54   return POLL(fds, nfds, timeout);
55 }
56
57 #endif
58
59 using namespace lldb;
60 using namespace lldb_private;
61
62 static sig_atomic_t g_signal_flags[NSIG];
63
64 #ifndef SIGNAL_POLLING_UNSUPPORTED
65 static void SignalHandler(int signo, siginfo_t *info, void *) {
66   assert(signo < NSIG);
67   g_signal_flags[signo] = 1;
68 }
69 #endif
70
71 class MainLoop::RunImpl {
72 public:
73   RunImpl(MainLoop &loop);
74   ~RunImpl() = default;
75
76   Status Poll();
77   void ProcessEvents();
78
79 private:
80   MainLoop &loop;
81
82 #if HAVE_SYS_EVENT_H
83   std::vector<struct kevent> in_events;
84   struct kevent out_events[4];
85   int num_events = -1;
86
87 #else
88 #ifdef __ANDROID__
89   fd_set read_fd_set;
90 #else
91   std::vector<struct pollfd> read_fds;
92 #endif
93
94   sigset_t get_sigmask();
95 #endif
96 };
97
98 #if HAVE_SYS_EVENT_H
99 MainLoop::RunImpl::RunImpl(MainLoop &loop) : loop(loop) {
100   in_events.reserve(loop.m_read_fds.size());
101 }
102
103 Status MainLoop::RunImpl::Poll() {
104   in_events.resize(loop.m_read_fds.size());
105   unsigned i = 0;
106   for (auto &fd : loop.m_read_fds)
107     EV_SET(&in_events[i++], fd.first, EVFILT_READ, EV_ADD, 0, 0, 0);
108
109   num_events = kevent(loop.m_kqueue, in_events.data(), in_events.size(),
110                       out_events, llvm::array_lengthof(out_events), nullptr);
111
112   if (num_events < 0) {
113     if (errno == EINTR) {
114       // in case of EINTR, let the main loop run one iteration
115       // we need to zero num_events to avoid assertions failing
116       num_events = 0;
117     } else
118       return Status(errno, eErrorTypePOSIX);
119   }
120   return Status();
121 }
122
123 void MainLoop::RunImpl::ProcessEvents() {
124   assert(num_events >= 0);
125   for (int i = 0; i < num_events; ++i) {
126     if (loop.m_terminate_request)
127       return;
128     switch (out_events[i].filter) {
129     case EVFILT_READ:
130       loop.ProcessReadObject(out_events[i].ident);
131       break;
132     case EVFILT_SIGNAL:
133       loop.ProcessSignal(out_events[i].ident);
134       break;
135     default:
136       llvm_unreachable("Unknown event");
137     }
138   }
139 }
140 #else
141 MainLoop::RunImpl::RunImpl(MainLoop &loop) : loop(loop) {
142 #ifndef __ANDROID__
143   read_fds.reserve(loop.m_read_fds.size());
144 #endif
145 }
146
147 sigset_t MainLoop::RunImpl::get_sigmask() {
148   sigset_t sigmask;
149 #if defined(_WIN32)
150   sigmask = 0;
151 #elif SIGNAL_POLLING_UNSUPPORTED
152   sigemptyset(&sigmask);
153 #else
154   int ret = pthread_sigmask(SIG_SETMASK, nullptr, &sigmask);
155   assert(ret == 0);
156   (void) ret;
157
158   for (const auto &sig : loop.m_signals)
159     sigdelset(&sigmask, sig.first);
160 #endif
161   return sigmask;
162 }
163
164 #ifdef __ANDROID__
165 Status MainLoop::RunImpl::Poll() {
166   // ppoll(2) is not supported on older all android versions. Also, older
167   // versions android (API <= 19) implemented pselect in a non-atomic way, as a
168   // combination of pthread_sigmask and select. This is not sufficient for us,
169   // as we rely on the atomicity to correctly implement signal polling, so we
170   // call the underlying syscall ourselves.
171
172   FD_ZERO(&read_fd_set);
173   int nfds = 0;
174   for (const auto &fd : loop.m_read_fds) {
175     FD_SET(fd.first, &read_fd_set);
176     nfds = std::max(nfds, fd.first + 1);
177   }
178
179   union {
180     sigset_t set;
181     uint64_t pad;
182   } kernel_sigset;
183   memset(&kernel_sigset, 0, sizeof(kernel_sigset));
184   kernel_sigset.set = get_sigmask();
185
186   struct {
187     void *sigset_ptr;
188     size_t sigset_len;
189   } extra_data = {&kernel_sigset, sizeof(kernel_sigset)};
190   if (syscall(__NR_pselect6, nfds, &read_fd_set, nullptr, nullptr, nullptr,
191               &extra_data) == -1 &&
192       errno != EINTR)
193     return Status(errno, eErrorTypePOSIX);
194
195   return Status();
196 }
197 #else
198 Status MainLoop::RunImpl::Poll() {
199   read_fds.clear();
200
201   sigset_t sigmask = get_sigmask();
202
203   for (const auto &fd : loop.m_read_fds) {
204     struct pollfd pfd;
205     pfd.fd = fd.first;
206     pfd.events = POLLIN;
207     pfd.revents = 0;
208     read_fds.push_back(pfd);
209   }
210
211   if (ppoll(read_fds.data(), read_fds.size(), nullptr, &sigmask) == -1 &&
212       errno != EINTR)
213     return Status(errno, eErrorTypePOSIX);
214
215   return Status();
216 }
217 #endif
218
219 void MainLoop::RunImpl::ProcessEvents() {
220 #ifdef __ANDROID__
221   // Collect first all readable file descriptors into a separate vector and
222   // then iterate over it to invoke callbacks. Iterating directly over
223   // loop.m_read_fds is not possible because the callbacks can modify the
224   // container which could invalidate the iterator.
225   std::vector<IOObject::WaitableHandle> fds;
226   for (const auto &fd : loop.m_read_fds)
227     if (FD_ISSET(fd.first, &read_fd_set))
228       fds.push_back(fd.first);
229
230   for (const auto &handle : fds) {
231 #else
232   for (const auto &fd : read_fds) {
233     if ((fd.revents & (POLLIN | POLLHUP)) == 0)
234       continue;
235     IOObject::WaitableHandle handle = fd.fd;
236 #endif
237     if (loop.m_terminate_request)
238       return;
239
240     loop.ProcessReadObject(handle);
241   }
242
243   std::vector<int> signals;
244   for (const auto &entry : loop.m_signals)
245     if (g_signal_flags[entry.first] != 0)
246       signals.push_back(entry.first);
247
248   for (const auto &signal : signals) {
249     if (loop.m_terminate_request)
250       return;
251     g_signal_flags[signal] = 0;
252     loop.ProcessSignal(signal);
253   }
254 }
255 #endif
256
257 MainLoop::MainLoop() {
258 #if HAVE_SYS_EVENT_H
259   m_kqueue = kqueue();
260   assert(m_kqueue >= 0);
261 #endif
262 }
263 MainLoop::~MainLoop() {
264 #if HAVE_SYS_EVENT_H
265   close(m_kqueue);
266 #endif
267   assert(m_read_fds.size() == 0);
268   assert(m_signals.size() == 0);
269 }
270
271 MainLoop::ReadHandleUP MainLoop::RegisterReadObject(const IOObjectSP &object_sp,
272                                                     const Callback &callback,
273                                                     Status &error) {
274 #ifdef _WIN32
275   if (object_sp->GetFdType() != IOObject:: eFDTypeSocket) {
276     error.SetErrorString("MainLoop: non-socket types unsupported on Windows");
277     return nullptr;
278   }
279 #endif
280   if (!object_sp || !object_sp->IsValid()) {
281     error.SetErrorString("IO object is not valid.");
282     return nullptr;
283   }
284
285   const bool inserted =
286       m_read_fds.insert({object_sp->GetWaitableHandle(), callback}).second;
287   if (!inserted) {
288     error.SetErrorStringWithFormat("File descriptor %d already monitored.",
289                                    object_sp->GetWaitableHandle());
290     return nullptr;
291   }
292
293   return CreateReadHandle(object_sp);
294 }
295
296 // We shall block the signal, then install the signal handler. The signal will
297 // be unblocked in the Run() function to check for signal delivery.
298 MainLoop::SignalHandleUP
299 MainLoop::RegisterSignal(int signo, const Callback &callback, Status &error) {
300 #ifdef SIGNAL_POLLING_UNSUPPORTED
301   error.SetErrorString("Signal polling is not supported on this platform.");
302   return nullptr;
303 #else
304   if (m_signals.find(signo) != m_signals.end()) {
305     error.SetErrorStringWithFormat("Signal %d already monitored.", signo);
306     return nullptr;
307   }
308
309   SignalInfo info;
310   info.callback = callback;
311   struct sigaction new_action;
312   new_action.sa_sigaction = &SignalHandler;
313   new_action.sa_flags = SA_SIGINFO;
314   sigemptyset(&new_action.sa_mask);
315   sigaddset(&new_action.sa_mask, signo);
316   sigset_t old_set;
317
318   g_signal_flags[signo] = 0;
319
320   // Even if using kqueue, the signal handler will still be invoked, so it's
321   // important to replace it with our "benign" handler.
322   int ret = sigaction(signo, &new_action, &info.old_action);
323   assert(ret == 0 && "sigaction failed");
324
325 #if HAVE_SYS_EVENT_H
326   struct kevent ev;
327   EV_SET(&ev, signo, EVFILT_SIGNAL, EV_ADD, 0, 0, 0);
328   ret = kevent(m_kqueue, &ev, 1, nullptr, 0, nullptr);
329   assert(ret == 0);
330 #endif
331
332   // If we're using kqueue, the signal needs to be unblocked in order to
333   // receive it. If using pselect/ppoll, we need to block it, and later unblock
334   // it as a part of the system call.
335   ret = pthread_sigmask(HAVE_SYS_EVENT_H ? SIG_UNBLOCK : SIG_BLOCK,
336                         &new_action.sa_mask, &old_set);
337   assert(ret == 0 && "pthread_sigmask failed");
338   info.was_blocked = sigismember(&old_set, signo);
339   m_signals.insert({signo, info});
340
341   return SignalHandleUP(new SignalHandle(*this, signo));
342 #endif
343 }
344
345 void MainLoop::UnregisterReadObject(IOObject::WaitableHandle handle) {
346   bool erased = m_read_fds.erase(handle);
347   UNUSED_IF_ASSERT_DISABLED(erased);
348   assert(erased);
349 }
350
351 void MainLoop::UnregisterSignal(int signo) {
352 #if SIGNAL_POLLING_UNSUPPORTED
353   Status("Signal polling is not supported on this platform.");
354 #else
355   auto it = m_signals.find(signo);
356   assert(it != m_signals.end());
357
358   sigaction(signo, &it->second.old_action, nullptr);
359
360   sigset_t set;
361   sigemptyset(&set);
362   sigaddset(&set, signo);
363   int ret = pthread_sigmask(it->second.was_blocked ? SIG_BLOCK : SIG_UNBLOCK,
364                             &set, nullptr);
365   assert(ret == 0);
366   (void)ret;
367
368 #if HAVE_SYS_EVENT_H
369   struct kevent ev;
370   EV_SET(&ev, signo, EVFILT_SIGNAL, EV_DELETE, 0, 0, 0);
371   ret = kevent(m_kqueue, &ev, 1, nullptr, 0, nullptr);
372   assert(ret == 0);
373 #endif
374
375   m_signals.erase(it);
376 #endif
377 }
378
379 Status MainLoop::Run() {
380   m_terminate_request = false;
381
382   Status error;
383   RunImpl impl(*this);
384
385   // run until termination or until we run out of things to listen to
386   while (!m_terminate_request && (!m_read_fds.empty() || !m_signals.empty())) {
387
388     error = impl.Poll();
389     if (error.Fail())
390       return error;
391
392     impl.ProcessEvents();
393   }
394   return Status();
395 }
396
397 void MainLoop::ProcessSignal(int signo) {
398   auto it = m_signals.find(signo);
399   if (it != m_signals.end())
400     it->second.callback(*this); // Do the work
401 }
402
403 void MainLoop::ProcessReadObject(IOObject::WaitableHandle handle) {
404   auto it = m_read_fds.find(handle);
405   if (it != m_read_fds.end())
406     it->second(*this); // Do the work
407 }