1 //===-- MainLoop.cpp --------------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "llvm/Config/llvm-config.h"
11 
12 #include "lldb/Host/MainLoop.h"
13 #include "lldb/Utility/Error.h"
14 #include <algorithm>
15 #include <cassert>
16 #include <cerrno>
17 #include <csignal>
18 #include <vector>
19 #include <time.h>
20 
21 #if HAVE_SYS_EVENT_H
22 #include <sys/event.h>
23 #elif defined(LLVM_ON_WIN32)
24 #include <winsock2.h>
25 #else
26 #include <poll.h>
27 #endif
28 
29 #ifdef LLVM_ON_WIN32
30 #define POLL WSAPoll
31 #else
32 #define POLL poll
33 #endif
34 
35 #ifdef __ANDROID__
36 #define FORCE_PSELECT
37 #endif
38 
39 #if SIGNAL_POLLING_UNSUPPORTED
40 #ifdef LLVM_ON_WIN32
41 typedef int sigset_t;
42 typedef int siginfo_t;
43 #endif
44 
45 int ppoll(struct pollfd *fds, size_t nfds, const struct timespec *timeout_ts,
46           const sigset_t *) {
47   int timeout =
48       (timeout_ts == nullptr)
49           ? -1
50           : (timeout_ts->tv_sec * 1000 + timeout_ts->tv_nsec / 1000000);
51   return POLL(fds, nfds, timeout);
52 }
53 
54 #endif
55 
56 using namespace lldb;
57 using namespace lldb_private;
58 
59 static sig_atomic_t g_signal_flags[NSIG];
60 
61 static void SignalHandler(int signo, siginfo_t *info, void *) {
62   assert(signo < NSIG);
63   g_signal_flags[signo] = 1;
64 }
65 
66 class MainLoop::RunImpl {
67 public:
68   // TODO: Use llvm::Expected<T>
69   static std::unique_ptr<RunImpl> Create(MainLoop &loop, Error &error);
70   ~RunImpl();
71 
72   Error Poll();
73 
74   template <typename F> void ForEachReadFD(F &&f);
75   template <typename F> void ForEachSignal(F &&f);
76 
77 private:
78   MainLoop &loop;
79 
80 #if HAVE_SYS_EVENT_H
81   int queue_id;
82   std::vector<struct kevent> in_events;
83   struct kevent out_events[4];
84   int num_events = -1;
85 
86   RunImpl(MainLoop &loop, int queue_id) : loop(loop), queue_id(queue_id) {
87     in_events.reserve(loop.m_read_fds.size() + loop.m_signals.size());
88   }
89 #else
90   std::vector<int> signals;
91 #ifdef FORCE_PSELECT
92   fd_set read_fd_set;
93 #else
94   std::vector<struct pollfd> read_fds;
95 #endif
96 
97   RunImpl(MainLoop &loop) : loop(loop) {
98     signals.reserve(loop.m_signals.size());
99   }
100 
101   sigset_t get_sigmask();
102 #endif
103 };
104 
105 #if HAVE_SYS_EVENT_H
106 MainLoop::RunImpl::~RunImpl() {
107   int r = close(queue_id);
108   assert(r == 0);
109   (void)r;
110 }
111 std::unique_ptr<MainLoop::RunImpl> MainLoop::RunImpl::Create(MainLoop &loop, Error &error)
112 {
113   error.Clear();
114   int queue_id = kqueue();
115   if(queue_id < 0) {
116     error = Error(errno, eErrorTypePOSIX);
117     return nullptr;
118   }
119   return std::unique_ptr<RunImpl>(new RunImpl(loop, queue_id));
120 }
121 
122 Error MainLoop::RunImpl::Poll() {
123   in_events.resize(loop.m_read_fds.size() + loop.m_signals.size());
124   unsigned i = 0;
125   for (auto &fd : loop.m_read_fds)
126     EV_SET(&in_events[i++], fd.first, EVFILT_READ, EV_ADD, 0, 0, 0);
127 
128   for (const auto &sig : loop.m_signals)
129     EV_SET(&in_events[i++], sig.first, EVFILT_SIGNAL, EV_ADD, 0, 0, 0);
130 
131   num_events = kevent(queue_id, in_events.data(), in_events.size(), out_events,
132                       llvm::array_lengthof(out_events), nullptr);
133 
134   if (num_events < 0)
135     return Error("kevent() failed with error %d\n", num_events);
136   return Error();
137 }
138 
139 template <typename F> void MainLoop::RunImpl::ForEachReadFD(F &&f) {
140   assert(num_events >= 0);
141   for (int i = 0; i < num_events; ++i) {
142     f(out_events[i].ident);
143     if (loop.m_terminate_request)
144       return;
145   }
146 }
147 template <typename F> void MainLoop::RunImpl::ForEachSignal(F && f) {}
148 #else
149 MainLoop::RunImpl::~RunImpl() {}
150 std::unique_ptr<MainLoop::RunImpl> MainLoop::RunImpl::Create(MainLoop &loop, Error &error)
151 {
152   error.Clear();
153   return std::unique_ptr<RunImpl>(new RunImpl(loop));
154 }
155 
156 sigset_t MainLoop::RunImpl::get_sigmask() {
157 #if SIGNAL_POLLING_UNSUPPORTED
158   return 0;
159 #else
160   sigset_t sigmask;
161   int ret = pthread_sigmask(SIG_SETMASK, nullptr, &sigmask);
162   assert(ret == 0);
163   (void) ret;
164 
165   for (const auto &sig : loop.m_signals) {
166     signals.push_back(sig.first);
167     sigdelset(&sigmask, sig.first);
168   }
169   return sigmask;
170 #endif
171 }
172 
173 #ifdef FORCE_PSELECT
174 Error MainLoop::RunImpl::Poll() {
175   signals.clear();
176 
177   FD_ZERO(&read_fd_set);
178   int nfds = 0;
179   for (const auto &fd : loop.m_read_fds) {
180     FD_SET(fd.first, &read_fd_set);
181     nfds = std::max(nfds, fd.first + 1);
182   }
183 
184   sigset_t sigmask = get_sigmask();
185   if (pselect(nfds, &read_fd_set, nullptr, nullptr, nullptr, &sigmask) == -1 &&
186       errno != EINTR)
187     return Error(errno, eErrorTypePOSIX);
188 
189   return Error();
190 }
191 
192 template <typename F> void MainLoop::RunImpl::ForEachReadFD(F &&f) {
193   for (const auto &fd : loop.m_read_fds) {
194     if(!FD_ISSET(fd.first, &read_fd_set))
195       continue;
196 
197     f(fd.first);
198     if (loop.m_terminate_request)
199       return;
200   }
201 }
202 #else
203 Error MainLoop::RunImpl::Poll() {
204   signals.clear();
205   read_fds.clear();
206 
207   sigset_t sigmask = get_sigmask();
208 
209   for (const auto &fd : loop.m_read_fds) {
210     struct pollfd pfd;
211     pfd.fd = fd.first;
212     pfd.events = POLLIN;
213     pfd.revents = 0;
214     read_fds.push_back(pfd);
215   }
216 
217   if (ppoll(read_fds.data(), read_fds.size(), nullptr, &sigmask) == -1 &&
218       errno != EINTR)
219     return Error(errno, eErrorTypePOSIX);
220 
221   return Error();
222 }
223 
224 template <typename F> void MainLoop::RunImpl::ForEachReadFD(F &&f) {
225   for (const auto &fd : read_fds) {
226     if ((fd.revents & POLLIN) == 0)
227       continue;
228 
229     f(fd.fd);
230     if (loop.m_terminate_request)
231       return;
232   }
233 }
234 #endif
235 
236 template <typename F> void MainLoop::RunImpl::ForEachSignal(F &&f) {
237   for (int sig : signals) {
238     if (g_signal_flags[sig] == 0)
239       continue; // No signal
240     g_signal_flags[sig] = 0;
241     f(sig);
242 
243     if (loop.m_terminate_request)
244       return;
245   }
246 }
247 #endif
248 
249 MainLoop::~MainLoop() {
250   assert(m_read_fds.size() == 0);
251   assert(m_signals.size() == 0);
252 }
253 
254 MainLoop::ReadHandleUP
255 MainLoop::RegisterReadObject(const IOObjectSP &object_sp,
256                                   const Callback &callback, Error &error) {
257 #ifdef LLVM_ON_WIN32
258   if (object_sp->GetFdType() != IOObject:: eFDTypeSocket) {
259     error.SetErrorString("MainLoop: non-socket types unsupported on Windows");
260     return nullptr;
261   }
262 #endif
263   if (!object_sp || !object_sp->IsValid()) {
264     error.SetErrorString("IO object is not valid.");
265     return nullptr;
266   }
267 
268   const bool inserted =
269       m_read_fds.insert({object_sp->GetWaitableHandle(), callback}).second;
270   if (!inserted) {
271     error.SetErrorStringWithFormat("File descriptor %d already monitored.",
272                                    object_sp->GetWaitableHandle());
273     return nullptr;
274   }
275 
276   return CreateReadHandle(object_sp);
277 }
278 
279 // We shall block the signal, then install the signal handler. The signal will
280 // be unblocked in
281 // the Run() function to check for signal delivery.
282 MainLoop::SignalHandleUP
283 MainLoop::RegisterSignal(int signo, const Callback &callback,
284                               Error &error) {
285 #ifdef SIGNAL_POLLING_UNSUPPORTED
286   error.SetErrorString("Signal polling is not supported on this platform.");
287   return nullptr;
288 #else
289   if (m_signals.find(signo) != m_signals.end()) {
290     error.SetErrorStringWithFormat("Signal %d already monitored.", signo);
291     return nullptr;
292   }
293 
294   SignalInfo info;
295   info.callback = callback;
296   struct sigaction new_action;
297   new_action.sa_sigaction = &SignalHandler;
298   new_action.sa_flags = SA_SIGINFO;
299   sigemptyset(&new_action.sa_mask);
300   sigaddset(&new_action.sa_mask, signo);
301 
302   sigset_t old_set;
303   if (int ret = pthread_sigmask(SIG_BLOCK, &new_action.sa_mask, &old_set)) {
304     error.SetErrorStringWithFormat("pthread_sigmask failed with error %d\n",
305                                    ret);
306     return nullptr;
307   }
308 
309   info.was_blocked = sigismember(&old_set, signo);
310   if (sigaction(signo, &new_action, &info.old_action) == -1) {
311     error.SetErrorToErrno();
312     if (!info.was_blocked)
313       pthread_sigmask(SIG_UNBLOCK, &new_action.sa_mask, nullptr);
314     return nullptr;
315   }
316 
317   m_signals.insert({signo, info});
318   g_signal_flags[signo] = 0;
319 
320   return SignalHandleUP(new SignalHandle(*this, signo));
321 #endif
322 }
323 
324 void MainLoop::UnregisterReadObject(IOObject::WaitableHandle handle) {
325   bool erased = m_read_fds.erase(handle);
326   UNUSED_IF_ASSERT_DISABLED(erased);
327   assert(erased);
328 }
329 
330 void MainLoop::UnregisterSignal(int signo) {
331 #if SIGNAL_POLLING_UNSUPPORTED
332   Error("Signal polling is not supported on this platform.");
333 #else
334   // We undo the actions of RegisterSignal on a best-effort basis.
335   auto it = m_signals.find(signo);
336   assert(it != m_signals.end());
337 
338   sigaction(signo, &it->second.old_action, nullptr);
339 
340   sigset_t set;
341   sigemptyset(&set);
342   sigaddset(&set, signo);
343   pthread_sigmask(it->second.was_blocked ? SIG_BLOCK : SIG_UNBLOCK, &set,
344                   nullptr);
345 
346   m_signals.erase(it);
347 #endif
348 }
349 
350 Error MainLoop::Run() {
351   m_terminate_request = false;
352 
353   Error error;
354   auto impl = RunImpl::Create(*this, error);
355   if (!impl)
356     return error;
357 
358   // run until termination or until we run out of things to listen to
359   while (!m_terminate_request && (!m_read_fds.empty() || !m_signals.empty())) {
360 
361     error = impl->Poll();
362     if (error.Fail())
363       return error;
364 
365     impl->ForEachSignal([&](int sig) {
366       auto it = m_signals.find(sig);
367       if (it != m_signals.end())
368         it->second.callback(*this); // Do the work
369     });
370     if (m_terminate_request)
371       return Error();
372 
373     impl->ForEachReadFD([&](int fd) {
374       auto it = m_read_fds.find(fd);
375       if (it != m_read_fds.end())
376         it->second(*this); // Do the work
377     });
378     if (m_terminate_request)
379       return Error();
380   }
381   return Error();
382 }
383