summaryrefslogtreecommitdiff
path: root/libs/binder/RpcSession.cpp
diff options
context:
space:
mode:
author Steven Moreland <smoreland@google.com> 2021-06-10 03:42:11 +0000
committer Steven Moreland <smoreland@google.com> 2021-06-12 00:22:10 +0000
commitc7d40135ed5fb30434c95f3058324b0af6916711 (patch)
tree41e639c646d22fe949ad824aae132ead462ffffb /libs/binder/RpcSession.cpp
parent5ae62560923bb111d3092d96a4ceb8cf3b8965d3 (diff)
libbinder: RPC disallow nested oneway transactions
Previously, nested transactions were accidentally allowed while processing oneway transactions. This changes things so that nested transactions are only explicitly allowed when a synchronous transaction is being processed (like how kernel binder is). Future considerations: this CL makes it more explicit that we allow refcount transactions as part of nested transactions. This is okay because 'drainCommands' will process these, but there might be some delay. We could make refcount behavior nicer if we always preferred using an active threadpool (if one is available) to process them. Bug: 167966510 Test: binderRpcTest Change-Id: Iaeb472896654ff4bcd75b20394f8f3230febaabf
Diffstat (limited to 'libs/binder/RpcSession.cpp')
-rw-r--r--libs/binder/RpcSession.cpp24
1 files changed, 19 insertions, 5 deletions
diff --git a/libs/binder/RpcSession.cpp b/libs/binder/RpcSession.cpp
index b2d1a1a869..4a6362a1ab 100644
--- a/libs/binder/RpcSession.cpp
+++ b/libs/binder/RpcSession.cpp
@@ -541,13 +541,27 @@ status_t RpcSession::ExclusiveConnection::find(const sp<RpcSession>& session, Co
(session->mClientConnectionsOffset + 1) % session->mClientConnections.size();
}
- // USE SERVING SOCKET (for nested transaction)
- //
- // asynchronous calls cannot be nested
+ // USE SERVING SOCKET (e.g. nested transaction)
if (use != ConnectionUse::CLIENT_ASYNC) {
+ sp<RpcConnection> exclusiveServer;
// server connections are always assigned to a thread
- findConnection(tid, &exclusive, nullptr /*available*/, session->mServerConnections,
- 0 /* index hint */);
+ findConnection(tid, &exclusiveServer, nullptr /*available*/,
+ session->mServerConnections, 0 /* index hint */);
+
+ // asynchronous calls cannot be nested, we currently allow ref count
+ // calls to be nested (so that you can use this without having extra
+ // threads). Note 'drainCommands' is used so that these ref counts can't
+ // build up.
+ if (exclusiveServer != nullptr) {
+ if (exclusiveServer->allowNested) {
+ // guaranteed to be processed as nested command
+ exclusive = exclusiveServer;
+ } else if (use == ConnectionUse::CLIENT_REFCOUNT && available == nullptr) {
+ // prefer available socket, but if we don't have one, don't
+ // wait for one
+ exclusive = exclusiveServer;
+ }
+ }
}
// if our thread is already using a connection, prioritize using that