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