Add a new Lock 'env_hooks_lock_' to avoid race conditions
For now, only TI agents would trigger AddEnvironmentHook() at runtime.
Test: art/test.py -b --host
Change-Id: I1d44b93e66a5cd98188bbac31ad21ce7a46923cb
diff --git a/runtime/jni/java_vm_ext.cc b/runtime/jni/java_vm_ext.cc
index dd45c32..12e6d22 100644
--- a/runtime/jni/java_vm_ext.cc
+++ b/runtime/jni/java_vm_ext.cc
@@ -509,6 +509,7 @@
weak_globals_add_condition_("weak globals add condition",
(CHECK(Locks::jni_weak_globals_lock_ != nullptr),
*Locks::jni_weak_globals_lock_)),
+ env_hooks_lock_("environment hooks lock", art::kGenericBottomLock),
env_hooks_(),
enable_allocation_tracking_delta_(
runtime_options.GetOrDefault(RuntimeArgumentMap::GlobalRefAllocStackTraceLimit)),
@@ -536,7 +537,12 @@
}
jint JavaVMExt::HandleGetEnv(/*out*/void** env, jint version) {
- for (GetEnvHook hook : env_hooks_) {
+ std::vector<GetEnvHook> env_hooks;
+ {
+ ReaderMutexLock rmu(Thread::Current(), env_hooks_lock_);
+ env_hooks.assign(env_hooks_.begin(), env_hooks_.end());
+ }
+ for (GetEnvHook hook : env_hooks) {
jint res = hook(this, env, version);
if (res == JNI_OK) {
return JNI_OK;
@@ -552,6 +558,7 @@
// Add a hook to handle getting environments from the GetEnv call.
void JavaVMExt::AddEnvironmentHook(GetEnvHook hook) {
CHECK(hook != nullptr) << "environment hooks shouldn't be null!";
+ WriterMutexLock wmu(Thread::Current(), env_hooks_lock_);
env_hooks_.push_back(hook);
}
diff --git a/runtime/jni/java_vm_ext.h b/runtime/jni/java_vm_ext.h
index a842efa..50e8414 100644
--- a/runtime/jni/java_vm_ext.h
+++ b/runtime/jni/java_vm_ext.h
@@ -200,9 +200,11 @@
void TrimGlobals() REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(!Locks::jni_globals_lock_);
- jint HandleGetEnv(/*out*/void** env, jint version);
+ jint HandleGetEnv(/*out*/void** env, jint version)
+ REQUIRES(!env_hooks_lock_);
- void AddEnvironmentHook(GetEnvHook hook);
+ void AddEnvironmentHook(GetEnvHook hook)
+ REQUIRES(!env_hooks_lock_);
static bool IsBadJniVersion(int version);
@@ -265,7 +267,8 @@
ConditionVariable weak_globals_add_condition_ GUARDED_BY(Locks::jni_weak_globals_lock_);
// TODO Maybe move this to Runtime.
- std::vector<GetEnvHook> env_hooks_;
+ ReaderWriterMutex env_hooks_lock_ BOTTOM_MUTEX_ACQUIRED_AFTER;
+ std::vector<GetEnvHook> env_hooks_ GUARDED_BY(env_hooks_lock_);
size_t enable_allocation_tracking_delta_;
std::atomic<bool> allocation_tracking_enabled_;