binder: libbinder_tls ensure to check trigger at least once.
If the SSL_write / SSL_read finishes in one round, we might have
never checked the fdTrigger. Ensure to check it at least once
before SSL_write / SSL_read.
Test: binderRpcTest
Bug: 190868302
Change-Id: I4588475354025f8f02d3eb998e9390d5babbc860
diff --git a/libs/binder/RpcTransportTls.cpp b/libs/binder/RpcTransportTls.cpp
index 6d39890..a102913 100644
--- a/libs/binder/RpcTransportTls.cpp
+++ b/libs/binder/RpcTransportTls.cpp
@@ -304,6 +304,8 @@
private:
android::base::unique_fd mSocket;
Ssl mSsl;
+
+ static status_t isTriggered(FdTrigger* fdTrigger);
};
// Error code is errno.
@@ -324,6 +326,15 @@
return ret;
}
+status_t RpcTransportTls::isTriggered(FdTrigger* fdTrigger) {
+ auto ret = fdTrigger->isTriggeredPolled();
+ if (!ret.ok()) {
+ ALOGE("%s: %s", __PRETTY_FUNCTION__, ret.error().message().c_str());
+ return ret.error().code() == 0 ? UNKNOWN_ERROR : -ret.error().code();
+ }
+ return OK;
+}
+
status_t RpcTransportTls::interruptableWriteFully(FdTrigger* fdTrigger, const void* data,
size_t size) {
auto buffer = reinterpret_cast<const uint8_t*>(data);
@@ -331,6 +342,10 @@
MAYBE_WAIT_IN_FLAKE_MODE;
+ // Before doing any I/O, check trigger once. This ensures the trigger is checked at least
+ // once. The trigger is also checked via triggerablePoll() after every SSL_write().
+ if (status_t status = isTriggered(fdTrigger); status != OK) return status;
+
while (buffer < end) {
size_t todo = std::min<size_t>(end - buffer, std::numeric_limits<int>::max());
auto [writeSize, errorQueue] = mSsl.call(SSL_write, buffer, todo);
@@ -358,6 +373,10 @@
MAYBE_WAIT_IN_FLAKE_MODE;
+ // Before doing any I/O, check trigger once. This ensures the trigger is checked at least
+ // once. The trigger is also checked via triggerablePoll() after every SSL_write().
+ if (status_t status = isTriggered(fdTrigger); status != OK) return status;
+
while (buffer < end) {
size_t todo = std::min<size_t>(end - buffer, std::numeric_limits<int>::max());
auto [readSize, errorQueue] = mSsl.call(SSL_read, buffer, todo);