| 117 | } |
| 118 | |
| 119 | void PidFdWaiter::WaitWorker() |
| 120 | { |
| 121 | struct epoll_event ev; |
| 122 | while (true) { |
| 123 | if (epoll_wait(epoll_fd_, &ev, 1, -1) == -1) { |
| 124 | XASSERT(errno == EINTR, "fail during epoll wait"); |
| 125 | continue; |
| 126 | } |
| 127 | |
| 128 | if (GetEventType(ev.data.u64) == kEpollEventTerminate) { |
| 129 | eventfd_t v; |
| 130 | XASSERT(!eventfd_read(event_fd_, &v), "fail to read event fd"); |
| 131 | return; |
| 132 | } |
| 133 | |
| 134 | XASSERT(GetEventType(ev.data.u64) == kEpollEventPid, |
| 135 | "invalid event type: %d", GetEventType(ev.data.u64)); |
| 136 | |
| 137 | PID pid = GetEventPid(ev.data.u64); |
| 138 | |
| 139 | mtx_.lock(); |
| 140 | auto it = pid_fds_.find(pid); |
| 141 | XASSERT(it != pid_fds_.end(), "pid fd not found"); |
| 142 | int pid_fd = it->second; |
| 143 | pid_fds_.erase(it); |
| 144 | mtx_.unlock(); |
| 145 | |
| 146 | XASSERT(!epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, pid_fd, nullptr), |
| 147 | "fail to remove pid fd from epoll"); |
| 148 | XASSERT(!close(pid_fd), "fail to close pid fd"); |
| 149 | callback_(pid); |
| 150 | } |
| 151 | } |
| 152 | |
| 153 | PID PidFdWaiter::GetEventPid(uint64_t data) |
| 154 | { |