diff options
author | 2021-06-29 18:44:56 -0700 | |
---|---|---|
committer | 2021-07-01 13:44:21 -0700 | |
commit | 0f9c5c7d0bc52e16438f7abb8b5060854ccb7867 (patch) | |
tree | 5e2bb939ba7b548933a90d0bad2509913c70c9b1 /libs/binder/RpcSession.cpp | |
parent | 7716e351eab610e41e454624937f8f1839aba027 (diff) |
RpcSession attaches/detaches JVM for Java thread
If javaAttachThread / javaDetachThread exists, run them before
and after the while loop in join. This ensures the
Java thread is attached / detached appropriately for
binder threads that handles RPC calls.
Test: run aservice on Java services
Bug: 190450693
Change-Id: I23f171dd1e08dfacfbbb46ecc9564cbf42d6f353
Diffstat (limited to 'libs/binder/RpcSession.cpp')
-rw-r--r-- | libs/binder/RpcSession.cpp | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/libs/binder/RpcSession.cpp b/libs/binder/RpcSession.cpp index ee5e8bb5bb..bdf1bbef02 100644 --- a/libs/binder/RpcSession.cpp +++ b/libs/binder/RpcSession.cpp @@ -18,13 +18,16 @@ #include <binder/RpcSession.h> +#include <dlfcn.h> #include <inttypes.h> #include <poll.h> +#include <pthread.h> #include <unistd.h> #include <string_view> #include <android-base/macros.h> +#include <android_runtime/threads.h> #include <binder/Parcel.h> #include <binder/RpcServer.h> #include <binder/Stability.h> @@ -274,10 +277,53 @@ RpcSession::PreJoinSetupResult RpcSession::preJoinSetup(base::unique_fd fd) { }; } +namespace { +// RAII object for attaching / detaching current thread to JVM if Android Runtime exists. If +// Android Runtime doesn't exist, no-op. +class JavaThreadAttacher { +public: + JavaThreadAttacher() { + // Use dlsym to find androidJavaAttachThread because libandroid_runtime is loaded after + // libbinder. + static auto attachFn = reinterpret_cast<decltype(&androidJavaAttachThread)>( + dlsym(RTLD_DEFAULT, "androidJavaAttachThread")); + if (attachFn == nullptr) return; + + char buf[16]; + const char* threadName = "UnknownRpcSessionThread"; // default thread name + if (0 == pthread_getname_np(pthread_self(), buf, sizeof(buf))) { + threadName = buf; + } + LOG_RPC_DETAIL("Attaching current thread %s to JVM", threadName); + LOG_ALWAYS_FATAL_IF(!attachFn(threadName), "Cannot attach thread %s to JVM", threadName); + mAttached = true; + } + ~JavaThreadAttacher() { + if (!mAttached) return; + static auto detachFn = reinterpret_cast<decltype(&androidJavaDetachThread)>( + dlsym(RTLD_DEFAULT, "androidJavaDetachThread")); + LOG_ALWAYS_FATAL_IF(detachFn == nullptr, + "androidJavaAttachThread exists but androidJavaDetachThread doesn't"); + + LOG_RPC_DETAIL("Detaching current thread from JVM"); + if (detachFn()) { + mAttached = false; + } else { + ALOGW("Unable to detach current thread from JVM"); + } + } + +private: + DISALLOW_COPY_AND_ASSIGN(JavaThreadAttacher); + bool mAttached = false; +}; +} // namespace + void RpcSession::join(sp<RpcSession>&& session, PreJoinSetupResult&& setupResult) { sp<RpcConnection>& connection = setupResult.connection; if (setupResult.status == OK) { + JavaThreadAttacher javaThreadAttacher; while (true) { status_t status = session->state()->getAndExecuteCommand(connection, session, RpcState::CommandType::ANY); |