diff options
author | 2021-07-14 23:19:25 +0000 | |
---|---|---|
committer | 2021-07-16 00:02:02 +0000 | |
commit | 798e0d1a492ae39ecba6b2b695808699234374f0 (patch) | |
tree | e1b9b5e1a2daf0ff793ddb8139658b6531a24467 /libs/binder/RpcSession.cpp | |
parent | e6d7b58981ca14d70dfec1b8b51c2b2f34060de0 (diff) |
libbinder: send is non-blocking and interruptible
We actually don't use MSG_DONTBLOCK now, but we only read after
receiving POLLOUT. However, by polling, send also now plugs into the
shutdown triggers. As a side effect, this causes send calls to fail
earlier.
Bug: 186470974
Test: binderRpcTest
Change-Id: Ia13d0dc1749fa7c10340e07e221b4b682cc59cc8
Diffstat (limited to 'libs/binder/RpcSession.cpp')
-rw-r--r-- | libs/binder/RpcSession.cpp | 31 |
1 files changed, 27 insertions, 4 deletions
diff --git a/libs/binder/RpcSession.cpp b/libs/binder/RpcSession.cpp index bdf1bbef02..fc6a900885 100644 --- a/libs/binder/RpcSession.cpp +++ b/libs/binder/RpcSession.cpp @@ -178,9 +178,11 @@ bool RpcSession::FdTrigger::isTriggered() { return mWrite == -1; } -status_t RpcSession::FdTrigger::triggerablePollRead(base::borrowed_fd fd) { +status_t RpcSession::FdTrigger::triggerablePoll(base::borrowed_fd fd, int16_t event) { while (true) { - pollfd pfd[]{{.fd = fd.get(), .events = POLLIN | POLLHUP, .revents = 0}, + pollfd pfd[]{{.fd = fd.get(), + .events = static_cast<int16_t>(event | POLLHUP), + .revents = 0}, {.fd = mRead.get(), .events = POLLHUP, .revents = 0}}; int ret = TEMP_FAILURE_RETRY(poll(pfd, arraysize(pfd), -1)); if (ret < 0) { @@ -192,10 +194,31 @@ status_t RpcSession::FdTrigger::triggerablePollRead(base::borrowed_fd fd) { if (pfd[1].revents & POLLHUP) { return -ECANCELED; } - return pfd[0].revents & POLLIN ? OK : DEAD_OBJECT; + return pfd[0].revents & event ? OK : DEAD_OBJECT; } } +status_t RpcSession::FdTrigger::interruptableWriteFully(base::borrowed_fd fd, const void* data, + size_t size) { + const uint8_t* buffer = reinterpret_cast<const uint8_t*>(data); + const uint8_t* end = buffer + size; + + MAYBE_WAIT_IN_FLAKE_MODE; + + status_t status; + while ((status = triggerablePoll(fd, POLLOUT)) == OK) { + ssize_t writeSize = TEMP_FAILURE_RETRY(send(fd.get(), buffer, end - buffer, MSG_NOSIGNAL)); + if (writeSize == 0) return DEAD_OBJECT; + + if (writeSize < 0) { + return -errno; + } + buffer += writeSize; + if (buffer == end) return OK; + } + return status; +} + status_t RpcSession::FdTrigger::interruptableReadFully(base::borrowed_fd fd, void* data, size_t size) { uint8_t* buffer = reinterpret_cast<uint8_t*>(data); @@ -204,7 +227,7 @@ status_t RpcSession::FdTrigger::interruptableReadFully(base::borrowed_fd fd, voi MAYBE_WAIT_IN_FLAKE_MODE; status_t status; - while ((status = triggerablePollRead(fd)) == OK) { + while ((status = triggerablePoll(fd, POLLIN)) == OK) { ssize_t readSize = TEMP_FAILURE_RETRY(recv(fd.get(), buffer, end - buffer, MSG_NOSIGNAL)); if (readSize == 0) return DEAD_OBJECT; // EOF |