shared_lib: Thread safety annotations to TrackEvent::GlobalState
* Add thread safety annotations.
* Fix a bug: GenerateDescriptorFromCategories() did not acquire the
required lock.
* Change struct to class, as recommended by google C++ style guidelines.
* Refer to `this` instead of `GlobalState::Instance()` in a couple of
places.
Change-Id: I759319df9e630ef1921d45171772f93ccb037b51
diff --git a/src/shared_lib/track_event.cc b/src/shared_lib/track_event.cc
index 6714032..4a0c70b 100644
--- a/src/shared_lib/track_event.cc
+++ b/src/shared_lib/track_event.cc
@@ -26,6 +26,7 @@
#include "perfetto/base/compiler.h"
#include "perfetto/base/flat_set.h"
+#include "perfetto/base/thread_annotations.h"
#include "perfetto/ext/base/file_utils.h"
#include "perfetto/ext/base/no_destructor.h"
#include "perfetto/ext/base/string_splitter.h"
@@ -307,14 +308,15 @@
static internal::DataSourceThreadLocalState** GetTlsState();
private:
- struct GlobalState {
+ class GlobalState {
+ public:
static GlobalState& Instance() {
static GlobalState* instance = new GlobalState();
return *instance;
}
void OnStart(const perfetto::protos::gen::TrackEventConfig& config,
- uint32_t instance_id) {
+ uint32_t instance_id) PERFETTO_LOCKS_EXCLUDED(mu_) {
std::lock_guard<std::mutex> lock(mu_);
EnableRegisteredCategory(perfetto_te_any_categories, instance_id);
for (PerfettoTeCategoryImpl* cat : categories_) {
@@ -324,15 +326,16 @@
}
}
- void OnStop(uint32_t instance_id) {
- std::lock_guard<std::mutex> lock(GlobalState::Instance().mu_);
- for (PerfettoTeCategoryImpl* cat : GlobalState::Instance().categories_) {
+ void OnStop(uint32_t instance_id) PERFETTO_LOCKS_EXCLUDED(mu_) {
+ std::lock_guard<std::mutex> lock(mu_);
+ for (PerfettoTeCategoryImpl* cat : categories_) {
DisableRegisteredCategory(cat, instance_id);
}
DisableRegisteredCategory(perfetto_te_any_categories, instance_id);
}
- void RegisterCategory(PerfettoTeCategoryImpl* cat) {
+ void RegisterCategory(PerfettoTeCategoryImpl* cat)
+ PERFETTO_LOCKS_EXCLUDED(mu_) {
{
std::lock_guard<std::mutex> lock(mu_);
Trace([cat](TraceContext ctx) {
@@ -343,11 +346,12 @@
}
});
categories_.push_back(cat);
- cat->cat_iid = ++GlobalState::Instance().interned_categories_;
+ cat->cat_iid = ++interned_categories_;
}
}
- void UnregisterCategory(PerfettoTeCategoryImpl* cat) {
+ void UnregisterCategory(PerfettoTeCategoryImpl* cat)
+ PERFETTO_LOCKS_EXCLUDED(mu_) {
std::lock_guard<std::mutex> lock(mu_);
categories_.erase(
std::remove(categories_.begin(), categories_.end(), cat),
@@ -356,7 +360,7 @@
void CategorySetCallback(struct PerfettoTeCategoryImpl* cat,
PerfettoTeCategoryImplCallback cb,
- void* user_arg) {
+ void* user_arg) PERFETTO_LOCKS_EXCLUDED(mu_) {
std::lock_guard<std::mutex> lock(mu_);
cat->cb = cb;
cat->cb_user_arg = user_arg;
@@ -376,14 +380,18 @@
}
}
- DataSourceDescriptor GenerateDescriptorFromCategories() const {
+ DataSourceDescriptor GenerateDescriptorFromCategories() const
+ PERFETTO_LOCKS_EXCLUDED(mu_) {
DataSourceDescriptor dsd;
dsd.set_name("track_event");
protozero::HeapBuffered<perfetto::protos::pbzero::TrackEventDescriptor>
ted;
- for (PerfettoTeCategoryImpl* cat : categories_) {
- SerializeCategory(*cat->desc, ted.get());
+ {
+ std::lock_guard<std::mutex> lock(mu_);
+ for (PerfettoTeCategoryImpl* cat : categories_) {
+ SerializeCategory(*cat->desc, ted.get());
+ }
}
dsd.set_track_event_descriptor_raw(ted.SerializeAsString());
return dsd;
@@ -395,10 +403,9 @@
perfetto_te_any_categories_enabled = &perfetto_te_any_categories->flag;
}
- // Guards categories and interned_categories;
- std::mutex mu_;
- std::vector<PerfettoTeCategoryImpl*> categories_;
- uint64_t interned_categories_;
+ mutable std::mutex mu_;
+ std::vector<PerfettoTeCategoryImpl*> categories_ PERFETTO_GUARDED_BY(mu_);
+ uint64_t interned_categories_ PERFETTO_GUARDED_BY(mu_);
};
uint32_t inst_id_;