diff options
-rw-r--r-- | libs/binder/RpcServer.cpp | 12 | ||||
-rw-r--r-- | libs/binder/RpcSession.cpp | 26 | ||||
-rw-r--r-- | libs/binder/include/binder/RpcSession.h | 4 |
3 files changed, 25 insertions, 17 deletions
diff --git a/libs/binder/RpcServer.cpp b/libs/binder/RpcServer.cpp index 540c346b87..e3bf2a5e36 100644 --- a/libs/binder/RpcServer.cpp +++ b/libs/binder/RpcServer.cpp @@ -151,9 +151,11 @@ void RpcServer::join() { LOG_ALWAYS_FATAL_IF(mShutdownTrigger == nullptr, "Cannot create join signaler"); } - while (mShutdownTrigger->triggerablePollRead(mServer)) { + status_t status; + while ((status = mShutdownTrigger->triggerablePollRead(mServer)) == OK) { (void)acceptOne(); } + LOG_RPC_DETAIL("RpcServer::join exiting with %s", statusToString(status).c_str()); { std::lock_guard<std::mutex> _l(mLock); @@ -236,9 +238,13 @@ void RpcServer::establishConnection(sp<RpcServer>&& server, base::unique_fd clie LOG_ALWAYS_FATAL_IF(server->mShutdownTrigger == nullptr); int32_t id; - bool idValid = server->mShutdownTrigger->interruptableRecv(clientFd.get(), &id, sizeof(id)); + status_t status = + server->mShutdownTrigger->interruptableReadFully(clientFd.get(), &id, sizeof(id)); + bool idValid = status == OK; if (!idValid) { - ALOGE("Failed to read ID for client connecting to RPC server."); + ALOGE("Failed to read ID for client connecting to RPC server: %s", + statusToString(status).c_str()); + // still need to cleanup before we can return } std::thread thisThread; diff --git a/libs/binder/RpcSession.cpp b/libs/binder/RpcSession.cpp index 771d738579..9f26a33335 100644 --- a/libs/binder/RpcSession.cpp +++ b/libs/binder/RpcSession.cpp @@ -125,39 +125,41 @@ void RpcSession::FdTrigger::trigger() { mWrite.reset(); } -bool RpcSession::FdTrigger::triggerablePollRead(base::borrowed_fd fd) { +status_t RpcSession::FdTrigger::triggerablePollRead(base::borrowed_fd fd) { while (true) { - pollfd pfd[]{{.fd = fd.get(), .events = POLLIN, .revents = 0}, + pollfd pfd[]{{.fd = fd.get(), .events = POLLIN | POLLHUP, .revents = 0}, {.fd = mRead.get(), .events = POLLHUP, .revents = 0}}; int ret = TEMP_FAILURE_RETRY(poll(pfd, arraysize(pfd), -1)); if (ret < 0) { - ALOGE("Could not poll: %s", strerror(errno)); - continue; + return -errno; } if (ret == 0) { continue; } if (pfd[1].revents & POLLHUP) { - return false; + return -ECANCELED; } - return true; + return pfd[0].revents & POLLIN ? OK : DEAD_OBJECT; } } -bool RpcSession::FdTrigger::interruptableRecv(base::borrowed_fd fd, void* data, size_t size) { +status_t RpcSession::FdTrigger::interruptableReadFully(base::borrowed_fd fd, void* data, + size_t size) { uint8_t* buffer = reinterpret_cast<uint8_t*>(data); uint8_t* end = buffer + size; - while (triggerablePollRead(fd)) { + status_t status; + while ((status = triggerablePollRead(fd)) == OK) { ssize_t readSize = TEMP_FAILURE_RETRY(recv(fd.get(), buffer, end - buffer, MSG_NOSIGNAL)); + if (readSize == 0) return DEAD_OBJECT; // EOF + if (readSize < 0) { - ALOGE("Failed to read %s", strerror(errno)); - return false; + return -errno; } buffer += readSize; - if (buffer == end) return true; + if (buffer == end) return OK; } - return false; + return status; } status_t RpcSession::readId() { diff --git a/libs/binder/include/binder/RpcSession.h b/libs/binder/include/binder/RpcSession.h index 3d22002c78..d6b796f281 100644 --- a/libs/binder/include/binder/RpcSession.h +++ b/libs/binder/include/binder/RpcSession.h @@ -132,7 +132,7 @@ private: * true - time to read! * false - trigger happened */ - bool triggerablePollRead(base::borrowed_fd fd); + status_t triggerablePollRead(base::borrowed_fd fd); /** * Read, but allow the read to be interrupted by this trigger. @@ -141,7 +141,7 @@ private: * true - read succeeded at 'size' * false - interrupted (failure or trigger) */ - bool interruptableRecv(base::borrowed_fd fd, void* data, size_t size); + status_t interruptableReadFully(base::borrowed_fd fd, void* data, size_t size); private: base::unique_fd mWrite; |