diff --git a/gin/public/v8_platform.h b/gin/public/v8_platform.h index ad37a5c4cebf7b..2dd32a055570bf 100644 --- a/gin/public/v8_platform.h +++ b/gin/public/v8_platform.h @@ -49,6 +49,9 @@ class GIN_EXPORT V8Platform : public NON_EXPORTED_BASE(v8::Platform) { const char* name, uint64_t handle) override; + void AddTraceStateObserver(v8::Platform::TraceStateObserver*) override; + void RemoveTraceStateObserver(v8::Platform::TraceStateObserver*) override; + private: friend struct base::DefaultLazyInstanceTraits; diff --git a/gin/v8_platform.cc b/gin/v8_platform.cc index 556f7fc5f24f0b..2bfc744a92673f 100644 --- a/gin/v8_platform.cc +++ b/gin/v8_platform.cc @@ -116,4 +116,66 @@ void V8Platform::UpdateTraceEventDuration(const uint8_t* category_enabled_flag, traceEventHandle); } +namespace { + +class EnabledStateObserverImpl final + : public base::trace_event::TraceLog::EnabledStateObserver { + public: + EnabledStateObserverImpl() = default; + + void OnTraceLogEnabled() final { + base::AutoLock lock(mutex_); + for (auto o : observers_) { + o->OnTraceEnabled(); + } + } + + void OnTraceLogDisabled() final { + base::AutoLock lock(mutex_); + for (auto o : observers_) { + o->OnTraceDisabled(); + } + } + + void AddObserver(v8::Platform::TraceStateObserver* observer) { + base::AutoLock lock(mutex_); + DCHECK(!observers_.count(observer)); + observers_.insert(observer); + if (observers_.size() == 1) { + base::trace_event::TraceLog::GetInstance()->AddEnabledStateObserver(this); + } + } + + void RemoveObserver(v8::Platform::TraceStateObserver* observer) { + base::AutoLock lock(mutex_); + DCHECK(observers_.count(observer) == 1); + observers_.erase(observer); + if (observers_.empty()) { + base::trace_event::TraceLog::GetInstance()->RemoveEnabledStateObserver( + this); + } + } + + private: + base::Lock mutex_; + std::unordered_set observers_; + + DISALLOW_COPY_AND_ASSIGN(EnabledStateObserverImpl); +}; + +base::LazyInstance::Leaky g_trace_state_dispatcher = + LAZY_INSTANCE_INITIALIZER; + +} // namespace + +void V8Platform::AddTraceStateObserver( + v8::Platform::TraceStateObserver* observer) { + g_trace_state_dispatcher.Get().AddObserver(observer); +} + +void V8Platform::RemoveTraceStateObserver( + v8::Platform::TraceStateObserver* observer) { + g_trace_state_dispatcher.Get().RemoveObserver(observer); +} + } // namespace gin