// Copyright 2016 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef BASE_TRACE_EVENT_AUTO_OPEN_CLOSE_EVENT_H_ #define BASE_TRACE_EVENT_AUTO_OPEN_CLOSE_EVENT_H_ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/threading/thread_checker.h" #include "base/time/time.h" #include "base/trace_event/trace_event.h" namespace base { namespace trace_event { // Class for tracing events that support "auto-opening" and "auto-closing". // "auto-opening" = if the trace event is started (call Begin() before // tracing is started,the trace event will be opened, with the start time // being the time that the trace event was actually started. // "auto-closing" = if the trace event is started but not ended by the time // tracing ends, then the trace event will be automatically closed at the // end of tracing. // |category| must be known at compile-time in order to be used in trace macros. // Hence, it's passed as a class templace argument. template class AutoOpenCloseEvent : public TraceLog::AsyncEnabledStateObserver { public: enum Type { ASYNC }; // As in the rest of the tracing macros, the const char* arguments here // must be pointers to indefinitely lived strings (e.g. hard-coded string // literals are okay, but not strings created by c_str()) AutoOpenCloseEvent(Type type, const char* event_name) : event_name_(event_name) { base::trace_event::TraceLog::GetInstance()->AddAsyncEnabledStateObserver( weak_factory_.GetWeakPtr()); } ~AutoOpenCloseEvent() override { DCHECK(thread_checker_.CalledOnValidThread()); base::trace_event::TraceLog::GetInstance()->RemoveAsyncEnabledStateObserver( this); } void Begin() { DCHECK(thread_checker_.CalledOnValidThread()); start_time_ = TRACE_TIME_TICKS_NOW(); TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP0( category, event_name_, static_cast(this), start_time_); } void End() { DCHECK(thread_checker_.CalledOnValidThread()); TRACE_EVENT_ASYNC_END0(category, event_name_, static_cast(this)); start_time_ = base::TimeTicks(); } // AsyncEnabledStateObserver implementation void OnTraceLogEnabled() override { DCHECK(thread_checker_.CalledOnValidThread()); if (!start_time_.is_null()) { TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP0( category, event_name_, static_cast(this), start_time_); } } void OnTraceLogDisabled() override {} private: const char* const event_name_; base::TimeTicks start_time_; base::ThreadChecker thread_checker_; WeakPtrFactory weak_factory_{this}; DISALLOW_COPY_AND_ASSIGN(AutoOpenCloseEvent); }; } // namespace trace_event } // namespace base #endif // BASE_TRACE_EVENT_AUTO_OPEN_CLOSE_EVENT_H_