summaryrefslogtreecommitdiff
path: root/runtime/jni/java_vm_ext.cc
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/jni/java_vm_ext.cc')
-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.