diff options
Diffstat (limited to 'runtime/jni/java_vm_ext.cc')
-rw-r--r-- | runtime/jni/java_vm_ext.cc | 15 |
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. |