diff options
Diffstat (limited to 'libs/input')
| -rw-r--r-- | libs/input/InputTransport.cpp | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/libs/input/InputTransport.cpp b/libs/input/InputTransport.cpp index fa094df159..37de00cf35 100644 --- a/libs/input/InputTransport.cpp +++ b/libs/input/InputTransport.cpp @@ -521,11 +521,11 @@ status_t InputChannel::receiveMessage(InputMessage* msg) { bool InputChannel::probablyHasInput() const { struct pollfd pfds = {.fd = mFd, .events = POLLIN}; if (::poll(&pfds, /*nfds=*/1, /*timeout=*/0) <= 0) { - // This can be a false negative because EAGAIN and ENOMEM are not handled. The latter should - // be extremely rare. The EAGAIN is also unlikely because it happens only when the signal - // arrives while the syscall is executed, and the syscall is quick. Hitting EAGAIN too often + // This can be a false negative because EINTR and ENOMEM are not handled. The latter should + // be extremely rare. The EINTR is also unlikely because it happens only when the signal + // arrives while the syscall is executed, and the syscall is quick. Hitting EINTR too often // would be a sign of having too many signals, which is a bigger performance problem. A - // common tradition is to repeat the syscall on each EAGAIN, but it is not necessary here. + // common tradition is to repeat the syscall on each EINTR, but it is not necessary here. // In other words, the missing one liner is replaced by a multiline explanation. return false; } @@ -534,6 +534,22 @@ bool InputChannel::probablyHasInput() const { return (pfds.revents & POLLIN) != 0; } +void InputChannel::waitForMessage(std::chrono::milliseconds timeout) const { + if (timeout < 0ms) { + LOG(FATAL) << "Timeout cannot be negative, received " << timeout.count(); + } + struct pollfd pfds = {.fd = mFd, .events = POLLIN}; + int ret; + std::chrono::time_point<std::chrono::steady_clock> stopTime = + std::chrono::steady_clock::now() + timeout; + std::chrono::milliseconds remaining = timeout; + do { + ret = ::poll(&pfds, /*nfds=*/1, /*timeout=*/remaining.count()); + remaining = std::chrono::duration_cast<std::chrono::milliseconds>( + stopTime - std::chrono::steady_clock::now()); + } while (ret == -1 && errno == EINTR && remaining > 0ms); +} + std::unique_ptr<InputChannel> InputChannel::dup() const { base::unique_fd newFd(dupFd()); return InputChannel::create(getName(), std::move(newFd), getConnectionToken()); |