summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Hans Boehm <hboehm@google.com> 2024-10-25 17:18:22 -0700
committer Hans Boehm <hboehm@google.com> 2024-10-27 02:47:36 +0000
commit5be7f7dab782b2a0629314f2b14a73b2ead301ce (patch)
tree0aeae4b4c614b140b1c4a54de82b0c058d8fe6d3
parente60598cab98ba513c7507d0ee63969bdc5dff38f (diff)
Don't block for long in UnloadNativeLibraries()
If we can't get jni_libraries_lock_ quickly give up, and let the next call to UnloadNativeLibraries() handle it. Bug: 74209523 Test: Treehugger Change-Id: I42bc812a38916bb626b025fde96118f670112c13
-rw-r--r--runtime/jni/java_vm_ext.cc15
1 files changed, 14 insertions, 1 deletions
diff --git a/runtime/jni/java_vm_ext.cc b/runtime/jni/java_vm_ext.cc
index 60b436984d..3012539b3c 100644
--- a/runtime/jni/java_vm_ext.cc
+++ b/runtime/jni/java_vm_ext.cc
@@ -353,7 +353,19 @@ class Libraries {
Thread* const self = Thread::Current();
std::vector<SharedLibrary*> unload_libraries;
{
- MutexLock mu(self, *Locks::jni_libraries_lock_);
+ // jni_libraries_lock_ appears to be held long enough that we just retry once, rather than
+ // spinning.
+ int retries = 0;
+ static constexpr int MAX_RETRIES = 5;
+ while (!Locks::jni_libraries_lock_->ExclusiveTryLock(self)) {
+ if (++retries > MAX_RETRIES) {
+ // We do not want to block indefinitely here, for fear of timeouts. See b/374209523.
+ LOG(WARNING) << "Deferring native library unloading due to contention";
+ return;
+ }
+ ScopedTrace("sleep 1 msec for jni_libraries_lock_");
+ usleep(1000);
+ }
for (auto it = libraries_.begin(); it != libraries_.end(); ) {
SharedLibrary* const library = it->second;
// If class loader is null then it was unloaded, call JNI_OnUnload.
@@ -367,6 +379,7 @@ class Libraries {
++it;
}
}
+ Locks::jni_libraries_lock_->ExclusiveUnlock(self);
}
ScopedThreadSuspension sts(self, ThreadState::kNative);
// Do this without holding the jni libraries lock to prevent possible deadlocks.