| 1794 | } |
| 1795 | |
| 1796 | void Poller::wait() noexcept { |
| 1797 | for (const auto &[NodeFd, FdData] : OldFdDatas) { |
| 1798 | if (auto Iter = FdDatas.find(NodeFd); Iter == FdDatas.end()) { |
| 1799 | // Remove unused event, ignore failed. |
| 1800 | // In kernel before 2.6.9, EPOLL_CTL_DEL required a non-null pointer. Use |
| 1801 | // `this` as the dummy parameter. |
| 1802 | ::epoll_ctl(Fd, EPOLL_CTL_DEL, NodeFd, |
| 1803 | reinterpret_cast<struct epoll_event *>(this)); |
| 1804 | } |
| 1805 | } |
| 1806 | |
| 1807 | EPollEvents.resize(Events.size()); |
| 1808 | const int Count = |
| 1809 | ::epoll_wait(Fd, EPollEvents.data(), EPollEvents.size(), -1); |
| 1810 | if (unlikely(Count < 0)) { |
| 1811 | const auto Error = fromErrNo(errno); |
| 1812 | for (auto &Event : Events) { |
| 1813 | Event.Valid = true; |
| 1814 | Event.error = Error; |
| 1815 | } |
| 1816 | return; |
| 1817 | } |
| 1818 | |
| 1819 | auto ProcessEvent = [](const struct epoll_event &EPollEvent, |
| 1820 | OptionalEvent &Event) noexcept { |
| 1821 | Event.Valid = true; |
| 1822 | Event.error = __WASI_ERRNO_SUCCESS; |
| 1823 | switch (Event.type) { |
| 1824 | case __WASI_EVENTTYPE_CLOCK: |
| 1825 | break; |
| 1826 | case __WASI_EVENTTYPE_FD_READ: { |
| 1827 | Event.fd_readwrite.flags = static_cast<__wasi_eventrwflags_t>(0); |
| 1828 | if (EPollEvent.events & EPOLLHUP) { |
| 1829 | Event.fd_readwrite.flags |= __WASI_EVENTRWFLAGS_FD_READWRITE_HANGUP; |
| 1830 | } |
| 1831 | bool UnknownNBytes = false; |
| 1832 | int ReadBufUsed = 0; |
| 1833 | if (auto Res = ::ioctl(EPollEvent.data.fd, FIONREAD, &ReadBufUsed); |
| 1834 | unlikely(Res == 0)) { |
| 1835 | UnknownNBytes = true; |
| 1836 | } |
| 1837 | if (UnknownNBytes) { |
| 1838 | Event.fd_readwrite.nbytes = 1; |
| 1839 | } else { |
| 1840 | Event.fd_readwrite.nbytes = ReadBufUsed; |
| 1841 | } |
| 1842 | break; |
| 1843 | } |
| 1844 | case __WASI_EVENTTYPE_FD_WRITE: { |
| 1845 | Event.fd_readwrite.flags = static_cast<__wasi_eventrwflags_t>(0); |
| 1846 | if (EPollEvent.events & EPOLLHUP) { |
| 1847 | Event.fd_readwrite.flags |= __WASI_EVENTRWFLAGS_FD_READWRITE_HANGUP; |
| 1848 | } |
| 1849 | bool UnknownNBytes = false; |
| 1850 | int WriteBufSize = 0; |
| 1851 | socklen_t IntSize = sizeof(WriteBufSize); |
| 1852 | if (auto Res = ::getsockopt(EPollEvent.data.fd, SOL_SOCKET, SO_SNDBUF, |
| 1853 | &WriteBufSize, &IntSize); |