summaryrefslogtreecommitdiff
path: root/libs/binder/RpcSession.cpp
diff options
context:
space:
mode:
author Steven Moreland <smoreland@google.com> 2021-07-14 23:19:25 +0000
committer Steven Moreland <smoreland@google.com> 2021-07-16 00:02:02 +0000
commit798e0d1a492ae39ecba6b2b695808699234374f0 (patch)
treee1b9b5e1a2daf0ff793ddb8139658b6531a24467 /libs/binder/RpcSession.cpp
parente6d7b58981ca14d70dfec1b8b51c2b2f34060de0 (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.cpp31
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