blob: 3e1964673ad25967ed91be45a9954c5ac88cc239 [file] [log] [blame]
Steven Moreland5553ac42020-11-11 02:14:45 +00001/*
2 * Copyright (C) 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "RpcConnection"
18
19#include <binder/RpcConnection.h>
20
Yifan Hong0d2bd112021-04-13 17:38:36 -070021#include <arpa/inet.h>
Yifan Hongb00ff662021-04-26 20:01:32 -070022#include <inttypes.h>
Yifan Hong0d2bd112021-04-13 17:38:36 -070023#include <netdb.h>
24#include <netinet/in.h>
25#include <sys/socket.h>
26#include <sys/types.h>
27#include <sys/un.h>
28#include <unistd.h>
29
30#include <string_view>
31
Steven Moreland5553ac42020-11-11 02:14:45 +000032#include <binder/Parcel.h>
33#include <binder/Stability.h>
Steven Morelandc1635952021-04-01 16:20:47 +000034#include <utils/String8.h>
Steven Moreland5553ac42020-11-11 02:14:45 +000035
36#include "RpcState.h"
37#include "RpcWireFormat.h"
38
Steven Morelandc1635952021-04-01 16:20:47 +000039#ifdef __GLIBC__
Steven Moreland5553ac42020-11-11 02:14:45 +000040extern "C" pid_t gettid();
41#endif
42
Steven Morelandc1635952021-04-01 16:20:47 +000043#ifdef __BIONIC__
44#include <linux/vm_sockets.h>
45#endif
46
Steven Moreland5553ac42020-11-11 02:14:45 +000047namespace android {
48
49using base::unique_fd;
Yifan Hong0d2bd112021-04-13 17:38:36 -070050using AddrInfo = std::unique_ptr<addrinfo, decltype(&freeaddrinfo)>;
Steven Moreland5553ac42020-11-11 02:14:45 +000051
Steven Morelandc1635952021-04-01 16:20:47 +000052RpcConnection::SocketAddress::~SocketAddress() {}
53
Steven Moreland5553ac42020-11-11 02:14:45 +000054RpcConnection::RpcConnection() {
55 LOG_RPC_DETAIL("RpcConnection created %p", this);
56
57 mState = std::make_unique<RpcState>();
58}
59RpcConnection::~RpcConnection() {
60 LOG_RPC_DETAIL("RpcConnection destroyed %p", this);
Steven Morelandaf816d82021-04-19 23:11:33 +000061
62 std::lock_guard<std::mutex> _l(mSocketMutex);
63 LOG_ALWAYS_FATAL_IF(mServers.size() != 0,
64 "Should not be able to destroy a connection with servers in use.");
Steven Moreland5553ac42020-11-11 02:14:45 +000065}
66
67sp<RpcConnection> RpcConnection::make() {
Steven Moreland1a3a8ef2021-04-02 02:52:46 +000068 return sp<RpcConnection>::make();
Steven Moreland5553ac42020-11-11 02:14:45 +000069}
70
Steven Morelandc1635952021-04-01 16:20:47 +000071class UnixSocketAddress : public RpcConnection::SocketAddress {
72public:
73 explicit UnixSocketAddress(const char* path) : mAddr({.sun_family = AF_UNIX}) {
74 unsigned int pathLen = strlen(path) + 1;
Steven Morelandcda60852021-04-14 23:45:32 +000075 LOG_ALWAYS_FATAL_IF(pathLen > sizeof(mAddr.sun_path), "Socket path is too long: %u %s",
76 pathLen, path);
Steven Morelandc1635952021-04-01 16:20:47 +000077 memcpy(mAddr.sun_path, path, pathLen);
78 }
79 virtual ~UnixSocketAddress() {}
80 std::string toString() const override {
81 return String8::format("path '%.*s'", static_cast<int>(sizeof(mAddr.sun_path)),
82 mAddr.sun_path)
83 .c_str();
84 }
85 const sockaddr* addr() const override { return reinterpret_cast<const sockaddr*>(&mAddr); }
86 size_t addrSize() const override { return sizeof(mAddr); }
87
88private:
89 sockaddr_un mAddr;
90};
91
Steven Moreland5553ac42020-11-11 02:14:45 +000092bool RpcConnection::setupUnixDomainServer(const char* path) {
Steven Morelandd47b32c2021-04-13 02:03:08 +000093 return setupSocketServer(UnixSocketAddress(path));
Steven Moreland5553ac42020-11-11 02:14:45 +000094}
95
Steven Morelandf137de92021-04-24 01:54:26 +000096bool RpcConnection::setupUnixDomainClient(const char* path) {
97 return setupSocketClient(UnixSocketAddress(path));
Steven Moreland53583542021-03-30 00:25:41 +000098}
99
Steven Morelandc1635952021-04-01 16:20:47 +0000100#ifdef __BIONIC__
101
102class VsockSocketAddress : public RpcConnection::SocketAddress {
103public:
104 VsockSocketAddress(unsigned int cid, unsigned int port)
105 : mAddr({
106 .svm_family = AF_VSOCK,
107 .svm_port = port,
108 .svm_cid = cid,
109 }) {}
110 virtual ~VsockSocketAddress() {}
111 std::string toString() const override {
Yifan Hong4c791532021-04-14 12:38:46 -0700112 return String8::format("cid %u port %u", mAddr.svm_cid, mAddr.svm_port).c_str();
Steven Morelandc1635952021-04-01 16:20:47 +0000113 }
114 const sockaddr* addr() const override { return reinterpret_cast<const sockaddr*>(&mAddr); }
115 size_t addrSize() const override { return sizeof(mAddr); }
116
117private:
118 sockaddr_vm mAddr;
119};
120
121bool RpcConnection::setupVsockServer(unsigned int port) {
122 // realizing value w/ this type at compile time to avoid ubsan abort
123 constexpr unsigned int kAnyCid = VMADDR_CID_ANY;
124
Steven Morelandd47b32c2021-04-13 02:03:08 +0000125 return setupSocketServer(VsockSocketAddress(kAnyCid, port));
Steven Morelandc1635952021-04-01 16:20:47 +0000126}
127
Steven Morelandf137de92021-04-24 01:54:26 +0000128bool RpcConnection::setupVsockClient(unsigned int cid, unsigned int port) {
129 return setupSocketClient(VsockSocketAddress(cid, port));
Steven Morelandc1635952021-04-01 16:20:47 +0000130}
131
132#endif // __BIONIC__
133
Steven Morelandd8996df2021-04-26 22:52:50 +0000134class InetSocketAddress : public RpcConnection::SocketAddress {
Yifan Hong0d2bd112021-04-13 17:38:36 -0700135public:
Steven Morelandd8996df2021-04-26 22:52:50 +0000136 InetSocketAddress(const sockaddr* sockAddr, size_t size, const char* addr, unsigned int port)
Steven Moreland158b63d2021-04-26 22:50:06 +0000137 : mSockAddr(sockAddr), mSize(size), mAddr(addr), mPort(port) {}
Yifan Hong0d2bd112021-04-13 17:38:36 -0700138 [[nodiscard]] std::string toString() const override {
Steven Moreland158b63d2021-04-26 22:50:06 +0000139 return String8::format("%s:%u", mAddr, mPort).c_str();
Yifan Hong0d2bd112021-04-13 17:38:36 -0700140 }
Steven Moreland158b63d2021-04-26 22:50:06 +0000141 [[nodiscard]] const sockaddr* addr() const override { return mSockAddr; }
Yifan Hong0d2bd112021-04-13 17:38:36 -0700142 [[nodiscard]] size_t addrSize() const override { return mSize; }
Yifan Hong0d2bd112021-04-13 17:38:36 -0700143
144private:
Steven Moreland158b63d2021-04-26 22:50:06 +0000145 const sockaddr* mSockAddr;
146 size_t mSize;
147 const char* mAddr;
148 unsigned int mPort;
Yifan Hong0d2bd112021-04-13 17:38:36 -0700149};
150
151AddrInfo GetAddrInfo(const char* addr, unsigned int port) {
152 addrinfo hint{
153 .ai_flags = 0,
154 .ai_family = AF_UNSPEC,
155 .ai_socktype = SOCK_STREAM,
156 .ai_protocol = 0,
157 };
158 addrinfo* aiStart = nullptr;
159 if (int rc = getaddrinfo(addr, std::to_string(port).data(), &hint, &aiStart); 0 != rc) {
160 ALOGE("Unable to resolve %s:%u: %s", addr, port, gai_strerror(rc));
161 return AddrInfo(nullptr, nullptr);
162 }
163 if (aiStart == nullptr) {
164 ALOGE("Unable to resolve %s:%u: getaddrinfo returns null", addr, port);
165 return AddrInfo(nullptr, nullptr);
166 }
167 return AddrInfo(aiStart, &freeaddrinfo);
168}
169
Yifan Hongb00ff662021-04-26 20:01:32 -0700170bool RpcConnection::setupInetServer(unsigned int port, unsigned int* assignedPort) {
Steven Moreland158b63d2021-04-26 22:50:06 +0000171 const char* kAddr = "127.0.0.1";
172
Yifan Hongb00ff662021-04-26 20:01:32 -0700173 if (assignedPort != nullptr) *assignedPort = 0;
Steven Moreland158b63d2021-04-26 22:50:06 +0000174 auto aiStart = GetAddrInfo(kAddr, port);
Yifan Hong0d2bd112021-04-13 17:38:36 -0700175 if (aiStart == nullptr) return false;
Yifan Hong0d2bd112021-04-13 17:38:36 -0700176 for (auto ai = aiStart.get(); ai != nullptr; ai = ai->ai_next) {
Steven Morelandd8996df2021-04-26 22:52:50 +0000177 InetSocketAddress socketAddress(ai->ai_addr, ai->ai_addrlen, kAddr, port);
Yifan Hongb00ff662021-04-26 20:01:32 -0700178 if (!setupSocketServer(socketAddress)) {
179 continue;
180 }
Steven Moreland2f1edfa2021-05-01 00:41:37 +0000181
182 LOG_ALWAYS_FATAL_IF(socketAddress.addr()->sa_family != AF_INET, "expecting inet");
183 sockaddr_in addr{};
184 socklen_t len = sizeof(addr);
185 if (0 != getsockname(mServer.get(), reinterpret_cast<sockaddr*>(&addr), &len)) {
186 int savedErrno = errno;
187 ALOGE("Could not getsockname at %s: %s", socketAddress.toString().c_str(),
188 strerror(savedErrno));
189 return false;
Yifan Hongb00ff662021-04-26 20:01:32 -0700190 }
Steven Moreland2f1edfa2021-05-01 00:41:37 +0000191 LOG_ALWAYS_FATAL_IF(len != sizeof(addr), "Wrong socket type: len %zu vs len %zu",
192 static_cast<size_t>(len), sizeof(addr));
193 unsigned int realPort = ntohs(addr.sin_port);
194 LOG_ALWAYS_FATAL_IF(port != 0 && realPort != port,
195 "Requesting inet server on %s but it is set up on %u.",
196 socketAddress.toString().c_str(), realPort);
197
198 if (assignedPort != nullptr) {
199 *assignedPort = realPort;
200 }
201
Yifan Hongb00ff662021-04-26 20:01:32 -0700202 return true;
Yifan Hong0d2bd112021-04-13 17:38:36 -0700203 }
Steven Moreland158b63d2021-04-26 22:50:06 +0000204 ALOGE("None of the socket address resolved for %s:%u can be set up as inet server.", kAddr,
Yifan Hong0d2bd112021-04-13 17:38:36 -0700205 port);
206 return false;
207}
208
Steven Morelandf137de92021-04-24 01:54:26 +0000209bool RpcConnection::setupInetClient(const char* addr, unsigned int port) {
Yifan Hong0d2bd112021-04-13 17:38:36 -0700210 auto aiStart = GetAddrInfo(addr, port);
211 if (aiStart == nullptr) return false;
Yifan Hong0d2bd112021-04-13 17:38:36 -0700212 for (auto ai = aiStart.get(); ai != nullptr; ai = ai->ai_next) {
Steven Morelandd8996df2021-04-26 22:52:50 +0000213 InetSocketAddress socketAddress(ai->ai_addr, ai->ai_addrlen, addr, port);
Steven Morelandf137de92021-04-24 01:54:26 +0000214 if (setupSocketClient(socketAddress)) return true;
Yifan Hong0d2bd112021-04-13 17:38:36 -0700215 }
216 ALOGE("None of the socket address resolved for %s:%u can be added as inet client.", addr, port);
217 return false;
218}
219
Steven Morelandd47b32c2021-04-13 02:03:08 +0000220bool RpcConnection::addNullDebuggingClient() {
221 unique_fd serverFd(TEMP_FAILURE_RETRY(open("/dev/null", O_WRONLY | O_CLOEXEC)));
222
223 if (serverFd == -1) {
224 ALOGE("Could not connect to /dev/null: %s", strerror(errno));
225 return false;
226 }
227
228 addClient(std::move(serverFd));
229 return true;
230}
231
Steven Moreland5553ac42020-11-11 02:14:45 +0000232sp<IBinder> RpcConnection::getRootObject() {
Steven Moreland1a3a8ef2021-04-02 02:52:46 +0000233 ExclusiveSocket socket(sp<RpcConnection>::fromExisting(this), SocketUse::CLIENT);
234 return state()->getRootObject(socket.fd(), sp<RpcConnection>::fromExisting(this));
Steven Moreland5553ac42020-11-11 02:14:45 +0000235}
236
Steven Morelandf137de92021-04-24 01:54:26 +0000237status_t RpcConnection::getMaxThreads(size_t* maxThreads) {
238 ExclusiveSocket socket(sp<RpcConnection>::fromExisting(this), SocketUse::CLIENT);
239 return state()->getMaxThreads(socket.fd(), sp<RpcConnection>::fromExisting(this), maxThreads);
240}
241
Steven Moreland5553ac42020-11-11 02:14:45 +0000242status_t RpcConnection::transact(const RpcAddress& address, uint32_t code, const Parcel& data,
243 Parcel* reply, uint32_t flags) {
Steven Moreland1a3a8ef2021-04-02 02:52:46 +0000244 ExclusiveSocket socket(sp<RpcConnection>::fromExisting(this),
Steven Moreland5553ac42020-11-11 02:14:45 +0000245 (flags & IBinder::FLAG_ONEWAY) ? SocketUse::CLIENT_ASYNC
246 : SocketUse::CLIENT);
Steven Moreland1a3a8ef2021-04-02 02:52:46 +0000247 return state()->transact(socket.fd(), address, code, data,
248 sp<RpcConnection>::fromExisting(this), reply, flags);
Steven Moreland5553ac42020-11-11 02:14:45 +0000249}
250
251status_t RpcConnection::sendDecStrong(const RpcAddress& address) {
Steven Moreland1a3a8ef2021-04-02 02:52:46 +0000252 ExclusiveSocket socket(sp<RpcConnection>::fromExisting(this), SocketUse::CLIENT_REFCOUNT);
Steven Moreland5553ac42020-11-11 02:14:45 +0000253 return state()->sendDecStrong(socket.fd(), address);
254}
255
256void RpcConnection::join() {
Steven Morelandaf816d82021-04-19 23:11:33 +0000257 // TODO(b/185167543): do this dynamically, instead of from a static number
258 // of threads
259 unique_fd clientFd(
260 TEMP_FAILURE_RETRY(accept4(mServer.get(), nullptr, 0 /*length*/, SOCK_CLOEXEC)));
261 if (clientFd < 0) {
262 // If this log becomes confusing, should save more state from setupUnixDomainServer
263 // in order to output here.
264 ALOGE("Could not accept4 socket: %s", strerror(errno));
265 return;
Steven Moreland5553ac42020-11-11 02:14:45 +0000266 }
267
Steven Morelandaf816d82021-04-19 23:11:33 +0000268 LOG_RPC_DETAIL("accept4 on fd %d yields fd %d", mServer.get(), clientFd.get());
269
270 // must be registered to allow arbitrary client code executing commands to
271 // be able to do nested calls (we can't only read from it)
272 sp<ConnectionSocket> socket = assignServerToThisThread(std::move(clientFd));
Steven Moreland5553ac42020-11-11 02:14:45 +0000273
274 while (true) {
Steven Moreland1a3a8ef2021-04-02 02:52:46 +0000275 status_t error =
Steven Morelandaf816d82021-04-19 23:11:33 +0000276 state()->getAndExecuteCommand(socket->fd, sp<RpcConnection>::fromExisting(this));
Steven Moreland5553ac42020-11-11 02:14:45 +0000277
278 if (error != OK) {
279 ALOGI("Binder socket thread closing w/ status %s", statusToString(error).c_str());
Steven Morelandaf816d82021-04-19 23:11:33 +0000280 break;
Steven Moreland5553ac42020-11-11 02:14:45 +0000281 }
282 }
Steven Morelandaf816d82021-04-19 23:11:33 +0000283
284 LOG_ALWAYS_FATAL_IF(!removeServerSocket(socket),
285 "bad state: socket object guaranteed to be in list");
Steven Moreland5553ac42020-11-11 02:14:45 +0000286}
287
288void RpcConnection::setForServer(const wp<RpcServer>& server) {
289 mForServer = server;
290}
291
292wp<RpcServer> RpcConnection::server() {
293 return mForServer;
294}
295
Steven Morelandd47b32c2021-04-13 02:03:08 +0000296bool RpcConnection::setupSocketServer(const SocketAddress& addr) {
Steven Morelandc1635952021-04-01 16:20:47 +0000297 LOG_ALWAYS_FATAL_IF(mServer.get() != -1, "Each RpcConnection can only have one server.");
298
299 unique_fd serverFd(
300 TEMP_FAILURE_RETRY(socket(addr.addr()->sa_family, SOCK_STREAM | SOCK_CLOEXEC, 0)));
301 if (serverFd == -1) {
302 ALOGE("Could not create socket: %s", strerror(errno));
303 return false;
304 }
305
306 if (0 != TEMP_FAILURE_RETRY(bind(serverFd.get(), addr.addr(), addr.addrSize()))) {
307 int savedErrno = errno;
308 ALOGE("Could not bind socket at %s: %s", addr.toString().c_str(), strerror(savedErrno));
309 return false;
310 }
311
312 if (0 != TEMP_FAILURE_RETRY(listen(serverFd.get(), 1 /*backlog*/))) {
313 int savedErrno = errno;
314 ALOGE("Could not listen socket at %s: %s", addr.toString().c_str(), strerror(savedErrno));
315 return false;
316 }
317
318 mServer = std::move(serverFd);
319 return true;
Steven Moreland53583542021-03-30 00:25:41 +0000320}
321
Steven Morelandf137de92021-04-24 01:54:26 +0000322bool RpcConnection::setupSocketClient(const SocketAddress& addr) {
323 {
324 std::lock_guard<std::mutex> _l(mSocketMutex);
325 LOG_ALWAYS_FATAL_IF(mClients.size() != 0,
326 "Must only setup connection once, but already has %zu clients",
327 mClients.size());
328 }
329
330 if (!setupOneSocketClient(addr)) return false;
331
332 // TODO(b/185167543): we should add additional connections dynamically
333 // instead of all at once.
334 // TODO(b/186470974): first risk of blocking
335 size_t numThreadsAvailable;
336 if (status_t status = getMaxThreads(&numThreadsAvailable); status != OK) {
337 ALOGE("Could not get max threads after initial connection to %s: %s",
338 addr.toString().c_str(), statusToString(status).c_str());
339 return false;
340 }
341
342 // we've already setup one client
343 for (size_t i = 0; i + 1 < numThreadsAvailable; i++) {
344 // TODO(b/185167543): avoid race w/ accept4 not being called on server
345 for (size_t tries = 0; tries < 5; tries++) {
346 if (setupOneSocketClient(addr)) break;
347 usleep(10000);
348 }
349 }
350
351 return true;
352}
353
354bool RpcConnection::setupOneSocketClient(const SocketAddress& addr) {
Steven Morelandc1635952021-04-01 16:20:47 +0000355 unique_fd serverFd(
356 TEMP_FAILURE_RETRY(socket(addr.addr()->sa_family, SOCK_STREAM | SOCK_CLOEXEC, 0)));
357 if (serverFd == -1) {
358 int savedErrno = errno;
359 ALOGE("Could not create socket at %s: %s", addr.toString().c_str(), strerror(savedErrno));
360 return false;
361 }
362
363 if (0 != TEMP_FAILURE_RETRY(connect(serverFd.get(), addr.addr(), addr.addrSize()))) {
364 int savedErrno = errno;
365 ALOGE("Could not connect socket at %s: %s", addr.toString().c_str(), strerror(savedErrno));
366 return false;
367 }
368
369 LOG_RPC_DETAIL("Socket at %s client with fd %d", addr.toString().c_str(), serverFd.get());
370
Steven Morelandd47b32c2021-04-13 02:03:08 +0000371 addClient(std::move(serverFd));
Steven Morelandc1635952021-04-01 16:20:47 +0000372 return true;
373}
374
Steven Morelanda4c94752021-05-01 01:34:24 +0000375void RpcConnection::addClient(unique_fd fd) {
Steven Morelandd47b32c2021-04-13 02:03:08 +0000376 std::lock_guard<std::mutex> _l(mSocketMutex);
377 sp<ConnectionSocket> connection = sp<ConnectionSocket>::make();
378 connection->fd = std::move(fd);
379 mClients.push_back(connection);
380}
381
Steven Morelanda4c94752021-05-01 01:34:24 +0000382sp<RpcConnection::ConnectionSocket> RpcConnection::assignServerToThisThread(unique_fd fd) {
Steven Moreland5553ac42020-11-11 02:14:45 +0000383 std::lock_guard<std::mutex> _l(mSocketMutex);
Steven Moreland1a3a8ef2021-04-02 02:52:46 +0000384 sp<ConnectionSocket> connection = sp<ConnectionSocket>::make();
Steven Moreland5553ac42020-11-11 02:14:45 +0000385 connection->fd = std::move(fd);
Steven Morelandaf816d82021-04-19 23:11:33 +0000386 connection->exclusiveTid = gettid();
Steven Moreland5553ac42020-11-11 02:14:45 +0000387 mServers.push_back(connection);
Steven Morelandaf816d82021-04-19 23:11:33 +0000388
389 return connection;
390}
391
392bool RpcConnection::removeServerSocket(const sp<ConnectionSocket>& socket) {
393 std::lock_guard<std::mutex> _l(mSocketMutex);
394 if (auto it = std::find(mServers.begin(), mServers.end(), socket); it != mServers.end()) {
395 mServers.erase(it);
396 return true;
397 }
398 return false;
Steven Moreland5553ac42020-11-11 02:14:45 +0000399}
400
401RpcConnection::ExclusiveSocket::ExclusiveSocket(const sp<RpcConnection>& connection, SocketUse use)
402 : mConnection(connection) {
403 pid_t tid = gettid();
404 std::unique_lock<std::mutex> _l(mConnection->mSocketMutex);
405
406 mConnection->mWaitingThreads++;
407 while (true) {
408 sp<ConnectionSocket> exclusive;
409 sp<ConnectionSocket> available;
410
411 // CHECK FOR DEDICATED CLIENT SOCKET
412 //
Steven Morelandaf816d82021-04-19 23:11:33 +0000413 // A server/looper should always use a dedicated connection if available
414 findSocket(tid, &exclusive, &available, mConnection->mClients, mConnection->mClientsOffset);
Steven Moreland5553ac42020-11-11 02:14:45 +0000415
Steven Morelandaf816d82021-04-19 23:11:33 +0000416 // WARNING: this assumes a server cannot request its client to send
417 // a transaction, as mServers is excluded below.
418 //
419 // Imagine we have more than one thread in play, and a single thread
420 // sends a synchronous, then an asynchronous command. Imagine the
421 // asynchronous command is sent on the first client socket. Then, if
422 // we naively send a synchronous command to that same socket, the
423 // thread on the far side might be busy processing the asynchronous
424 // command. So, we move to considering the second available thread
425 // for subsequent calls.
426 if (use == SocketUse::CLIENT_ASYNC && (exclusive != nullptr || available != nullptr)) {
427 mConnection->mClientsOffset =
428 (mConnection->mClientsOffset + 1) % mConnection->mClients.size();
Steven Moreland5553ac42020-11-11 02:14:45 +0000429 }
430
Steven Morelandaf816d82021-04-19 23:11:33 +0000431 // USE SERVING SOCKET (for nested transaction)
Steven Moreland5553ac42020-11-11 02:14:45 +0000432 //
433 // asynchronous calls cannot be nested
434 if (use != SocketUse::CLIENT_ASYNC) {
Steven Morelandaf816d82021-04-19 23:11:33 +0000435 // server sockets are always assigned to a thread
436 findSocket(tid, &exclusive, nullptr /*available*/, mConnection->mServers,
437 0 /* index hint */);
Steven Moreland5553ac42020-11-11 02:14:45 +0000438 }
439
440 // if our thread is already using a connection, prioritize using that
441 if (exclusive != nullptr) {
442 mSocket = exclusive;
443 mReentrant = true;
444 break;
445 } else if (available != nullptr) {
446 mSocket = available;
447 mSocket->exclusiveTid = tid;
448 break;
449 }
450
Steven Moreland5553ac42020-11-11 02:14:45 +0000451 // in regular binder, this would usually be a deadlock :)
452 LOG_ALWAYS_FATAL_IF(mConnection->mClients.size() == 0,
453 "Not a client of any connection. You must create a connection to an "
454 "RPC server to make any non-nested (e.g. oneway or on another thread) "
455 "calls.");
456
457 LOG_RPC_DETAIL("No available connection (have %zu clients and %zu servers). Waiting...",
458 mConnection->mClients.size(), mConnection->mServers.size());
459 mConnection->mSocketCv.wait(_l);
460 }
461 mConnection->mWaitingThreads--;
462}
463
464void RpcConnection::ExclusiveSocket::findSocket(pid_t tid, sp<ConnectionSocket>* exclusive,
465 sp<ConnectionSocket>* available,
466 std::vector<sp<ConnectionSocket>>& sockets,
467 size_t socketsIndexHint) {
468 LOG_ALWAYS_FATAL_IF(sockets.size() > 0 && socketsIndexHint >= sockets.size(),
469 "Bad index %zu >= %zu", socketsIndexHint, sockets.size());
470
471 if (*exclusive != nullptr) return; // consistent with break below
472
473 for (size_t i = 0; i < sockets.size(); i++) {
474 sp<ConnectionSocket>& socket = sockets[(i + socketsIndexHint) % sockets.size()];
475
476 // take first available connection (intuition = caching)
477 if (available && *available == nullptr && socket->exclusiveTid == std::nullopt) {
478 *available = socket;
479 continue;
480 }
481
482 // though, prefer to take connection which is already inuse by this thread
483 // (nested transactions)
484 if (exclusive && socket->exclusiveTid == tid) {
485 *exclusive = socket;
486 break; // consistent with return above
487 }
488 }
489}
490
491RpcConnection::ExclusiveSocket::~ExclusiveSocket() {
492 // reentrant use of a connection means something less deep in the call stack
493 // is using this fd, and it retains the right to it. So, we don't give up
494 // exclusive ownership, and no thread is freed.
495 if (!mReentrant) {
496 std::unique_lock<std::mutex> _l(mConnection->mSocketMutex);
497 mSocket->exclusiveTid = std::nullopt;
498 if (mConnection->mWaitingThreads > 0) {
499 _l.unlock();
500 mConnection->mSocketCv.notify_one();
501 }
502 }
503}
504
505} // namespace android