Make CompatFramework::ReportChange thread safe
Guard accesses to reported_compat_changes_ with
reported_compat_changes_lock_. Guarding disabled_compat_changes_ should
not be necessary, as it's initialized synchronously early after zygote
fork, never to be changed afterwards.
Bug: 174843201
Test: manual
Change-Id: I73b5dadf0576c2bc163602f566486172c35dd78d
diff --git a/runtime/compat_framework.cc b/runtime/compat_framework.cc
index 40c4540..17d423b 100644
--- a/runtime/compat_framework.cc
+++ b/runtime/compat_framework.cc
@@ -16,10 +16,12 @@
#include "compat_framework.h"
-#include "android-base/logging.h"
#include <sys/types.h>
#include <unistd.h>
+#include "android-base/logging.h"
+#include "thread-current-inl.h"
+
namespace art {
// Compat change states as strings.
@@ -28,6 +30,11 @@
static constexpr char kDisabledChangeState[] = "DISABLED";
static constexpr char kLoggedState[] = "LOGGED";
+CompatFramework::CompatFramework()
+ : reported_compat_changes_lock_("reported compat changes lock") {}
+
+CompatFramework::~CompatFramework() {}
+
bool CompatFramework::IsChangeEnabled(uint64_t change_id) {
const auto enabled = disabled_compat_changes_.count(change_id) == 0;
ReportChange(change_id, enabled ? ChangeState::kEnabled : ChangeState::kDisabled);
@@ -39,6 +46,7 @@
}
void CompatFramework::ReportChange(uint64_t change_id, ChangeState state) {
+ MutexLock mu(Thread::Current(), reported_compat_changes_lock_);
bool already_reported = reported_compat_changes_.count(change_id) != 0;
if (already_reported) {
return;
diff --git a/runtime/compat_framework.h b/runtime/compat_framework.h
index bc628d2..99a9215 100644
--- a/runtime/compat_framework.h
+++ b/runtime/compat_framework.h
@@ -19,6 +19,8 @@
#include <set>
+#include "base/macros.h"
+#include "base/mutex.h"
#include "base/string_view_cpp20.h"
namespace art {
@@ -37,6 +39,9 @@
kLogged
};
+ CompatFramework();
+ ~CompatFramework();
+
void SetDisabledCompatChanges(const std::set<uint64_t>& disabled_changes) {
disabled_compat_changes_ = disabled_changes;
}
@@ -64,8 +69,9 @@
// A set of disabled compat changes for the running app, all other changes are enabled.
std::set<uint64_t> disabled_compat_changes_;
- // A set of repoted compat changes for the running app.
- std::set<uint64_t> reported_compat_changes_;
+ // A set of reported compat changes for the running app.
+ std::set<uint64_t> reported_compat_changes_ GUARDED_BY(reported_compat_changes_lock_);
+ Mutex reported_compat_changes_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
};
} // namespace art