diff options
author | 2022-03-19 02:34:57 +0000 | |
---|---|---|
committer | 2022-05-17 00:58:36 +0000 | |
commit | 1975aaa532eeeea97980718cd68c4101fcdf6b97 (patch) | |
tree | d9158b8b87d7c6288afbfe2dec1547b95b0d3dfd | |
parent | 97c1356a08376bd1664a0ce5be5591fe9c91c7d6 (diff) |
libbinder: replace RpcTransport::peek() with pollRead()
peek uses MSG_PEEK internally which only works with sockets.
This refactors that function into a more specific pollRead()
which works for e.g. pipes and other files.
Bug: 224644083
Test: atest binderRpcTest
Change-Id: I340fa7ee7a7bb2077115fc28835bcadf67db03d9
-rw-r--r-- | libs/binder/RpcState.cpp | 5 | ||||
-rw-r--r-- | libs/binder/RpcTransportRaw.cpp | 11 | ||||
-rw-r--r-- | libs/binder/RpcTransportTls.cpp | 9 | ||||
-rw-r--r-- | libs/binder/include/binder/RpcTransport.h | 11 |
4 files changed, 21 insertions, 15 deletions
diff --git a/libs/binder/RpcState.cpp b/libs/binder/RpcState.cpp index 6d89064a5d..4ef9cd859d 100644 --- a/libs/binder/RpcState.cpp +++ b/libs/binder/RpcState.cpp @@ -661,13 +661,10 @@ status_t RpcState::getAndExecuteCommand(const sp<RpcSession::RpcConnection>& con status_t RpcState::drainCommands(const sp<RpcSession::RpcConnection>& connection, const sp<RpcSession>& session, CommandType type) { - uint8_t buf; while (true) { - size_t num_bytes; - status_t status = connection->rpcTransport->peek(&buf, sizeof(buf), &num_bytes); + status_t status = connection->rpcTransport->pollRead(); if (status == WOULD_BLOCK) break; if (status != OK) return status; - if (!num_bytes) break; status = getAndExecuteCommand(connection, session, type); if (status != OK) return status; diff --git a/libs/binder/RpcTransportRaw.cpp b/libs/binder/RpcTransportRaw.cpp index 7cfc78082e..f5cc41332e 100644 --- a/libs/binder/RpcTransportRaw.cpp +++ b/libs/binder/RpcTransportRaw.cpp @@ -32,19 +32,22 @@ namespace { class RpcTransportRaw : public RpcTransport { public: explicit RpcTransportRaw(android::base::unique_fd socket) : mSocket(std::move(socket)) {} - status_t peek(void* buf, size_t size, size_t* out_size) override { - ssize_t ret = TEMP_FAILURE_RETRY(::recv(mSocket.get(), buf, size, MSG_PEEK)); + status_t pollRead(void) override { + uint8_t buf; + ssize_t ret = TEMP_FAILURE_RETRY( + ::recv(mSocket.get(), &buf, sizeof(buf), MSG_PEEK | MSG_DONTWAIT)); if (ret < 0) { int savedErrno = errno; if (savedErrno == EAGAIN || savedErrno == EWOULDBLOCK) { return WOULD_BLOCK; } - LOG_RPC_DETAIL("RpcTransport peek(): %s", strerror(savedErrno)); + LOG_RPC_DETAIL("RpcTransport poll(): %s", strerror(savedErrno)); return -savedErrno; + } else if (ret == 0) { + return DEAD_OBJECT; } - *out_size = static_cast<size_t>(ret); return OK; } diff --git a/libs/binder/RpcTransportTls.cpp b/libs/binder/RpcTransportTls.cpp index bc68c379ce..85c7655727 100644 --- a/libs/binder/RpcTransportTls.cpp +++ b/libs/binder/RpcTransportTls.cpp @@ -277,7 +277,7 @@ class RpcTransportTls : public RpcTransport { public: RpcTransportTls(android::base::unique_fd socket, Ssl ssl) : mSocket(std::move(socket)), mSsl(std::move(ssl)) {} - status_t peek(void* buf, size_t size, size_t* out_size) override; + status_t pollRead(void) override; status_t interruptableWriteFully(FdTrigger* fdTrigger, iovec* iovs, int niovs, const std::function<status_t()>& altPoll) override; status_t interruptableReadFully(FdTrigger* fdTrigger, iovec* iovs, int niovs, @@ -289,9 +289,9 @@ private: }; // Error code is errno. -status_t RpcTransportTls::peek(void* buf, size_t size, size_t* out_size) { - size_t todo = std::min<size_t>(size, std::numeric_limits<int>::max()); - auto [ret, errorQueue] = mSsl.call(SSL_peek, buf, static_cast<int>(todo)); +status_t RpcTransportTls::pollRead(void) { + uint8_t buf; + auto [ret, errorQueue] = mSsl.call(SSL_peek, &buf, sizeof(buf)); if (ret < 0) { int err = mSsl.getError(ret); if (err == SSL_ERROR_WANT_WRITE || err == SSL_ERROR_WANT_READ) { @@ -304,7 +304,6 @@ status_t RpcTransportTls::peek(void* buf, size_t size, size_t* out_size) { } errorQueue.clear(); LOG_TLS_DETAIL("TLS: Peeked %d bytes!", ret); - *out_size = static_cast<size_t>(ret); return OK; } diff --git a/libs/binder/include/binder/RpcTransport.h b/libs/binder/include/binder/RpcTransport.h index 751c4f905d..2c864f82f5 100644 --- a/libs/binder/include/binder/RpcTransport.h +++ b/libs/binder/include/binder/RpcTransport.h @@ -39,8 +39,15 @@ class RpcTransport { public: virtual ~RpcTransport() = default; - // replacement of ::recv(MSG_PEEK). Error code may not be set if TLS is enabled. - [[nodiscard]] virtual status_t peek(void *buf, size_t size, size_t *out_size) = 0; + /** + * Poll the transport to check whether there is any data ready to read. + * + * Return: + * OK - There is data available on this transport + * WOULDBLOCK - No data is available + * error - any other error + */ + [[nodiscard]] virtual status_t pollRead(void) = 0; /** * Read (or write), but allow to be interrupted by a trigger. |