summaryrefslogtreecommitdiff
path: root/libs/binder/RpcSession.cpp
diff options
context:
space:
mode:
author Steven Moreland <smoreland@google.com> 2021-06-08 01:27:53 +0000
committer Steven Moreland <smoreland@google.com> 2021-06-08 01:39:40 +0000
commita8b4429c398a79e4454015cbb309514b97484451 (patch)
treea15229fe42c756e1ae8e59f07a01d219cfa006fe /libs/binder/RpcSession.cpp
parent4e10feb3a1f3d2c4f61a4e81e664debbd8fb3551 (diff)
libbinder: server sessions shut down independently
Before this CL, for a server, there is a single pipe which when hungup will end every session with that server. This, as it turned out in hindsight to be problematic, since we want to shutdown problematic sessions without interrupting other clients. Assuming we keep the pipe-based interrupt, there are essential two solutions to consider here (this CL is option B). a. instead of hanging up these pipes, write information to them, and then wake up all relevant threads which can figure out the right thing to do. - pro: only need to create one FD - con: very complicated because there may be multiple readers of the pipe, etc... - con: will mess with all clients b. have a separate pipe per session - pro: relatively simple logic - con: an extra FD per session So, for now, going with (b). Bug: 183140903 Test: binderRpcTest, run biner_rpc_fuzzer for 5 minutes (I checked locally, w/o the RpcServer check for isTriggered, this also detected that deadlock in less than 1 minute! :D) Change-Id: I9e290cd0a6df1d33435183fb16f508f38071ad62
Diffstat (limited to 'libs/binder/RpcSession.cpp')
-rw-r--r--libs/binder/RpcSession.cpp20
1 files changed, 14 insertions, 6 deletions
diff --git a/libs/binder/RpcSession.cpp b/libs/binder/RpcSession.cpp
index c5633771d0..93e04f7558 100644
--- a/libs/binder/RpcSession.cpp
+++ b/libs/binder/RpcSession.cpp
@@ -144,7 +144,10 @@ status_t RpcSession::sendDecStrong(const RpcAddress& address) {
std::unique_ptr<RpcSession::FdTrigger> RpcSession::FdTrigger::make() {
auto ret = std::make_unique<RpcSession::FdTrigger>();
- if (!android::base::Pipe(&ret->mRead, &ret->mWrite)) return nullptr;
+ if (!android::base::Pipe(&ret->mRead, &ret->mWrite)) {
+ ALOGE("Could not create pipe %s", strerror(errno));
+ return nullptr;
+ }
return ret;
}
@@ -152,6 +155,10 @@ void RpcSession::FdTrigger::trigger() {
mWrite.reset();
}
+bool RpcSession::FdTrigger::isTriggered() {
+ return mWrite == -1;
+}
+
status_t RpcSession::FdTrigger::triggerablePollRead(base::borrowed_fd fd) {
while (true) {
pollfd pfd[]{{.fd = fd.get(), .events = POLLIN | POLLHUP, .revents = 0},
@@ -408,20 +415,21 @@ bool RpcSession::addClientConnection(unique_fd fd) {
return true;
}
-void RpcSession::setForServer(const wp<RpcServer>& server, const wp<EventListener>& eventListener,
- int32_t sessionId,
- const std::shared_ptr<FdTrigger>& shutdownTrigger) {
+bool RpcSession::setForServer(const wp<RpcServer>& server, const wp<EventListener>& eventListener,
+ int32_t sessionId) {
LOG_ALWAYS_FATAL_IF(mForServer != nullptr);
LOG_ALWAYS_FATAL_IF(server == nullptr);
LOG_ALWAYS_FATAL_IF(mEventListener != nullptr);
LOG_ALWAYS_FATAL_IF(eventListener == nullptr);
LOG_ALWAYS_FATAL_IF(mShutdownTrigger != nullptr);
- LOG_ALWAYS_FATAL_IF(shutdownTrigger == nullptr);
+
+ mShutdownTrigger = FdTrigger::make();
+ if (mShutdownTrigger == nullptr) return false;
mId = sessionId;
mForServer = server;
mEventListener = eventListener;
- mShutdownTrigger = shutdownTrigger;
+ return true;
}
sp<RpcSession::RpcConnection> RpcSession::assignServerToThisThread(unique_fd fd) {