client lib: Support initializing multiple times
Turns out many callsites of client lib's init functions need explicit
checks to ensure initializing it only once. Instead, build the check
into the client lib itself.
Change-Id: I487aac3b2a76d2357387a2154b89c800bccf0b79
diff --git a/include/perfetto/tracing/tracing.h b/include/perfetto/tracing/tracing.h
index 023e6f0..61e805c 100644
--- a/include/perfetto/tracing/tracing.h
+++ b/include/perfetto/tracing/tracing.h
@@ -75,6 +75,14 @@
// Must be one of [4, 8, 16, 32].
uint32_t shmem_page_size_hint_kb = 0;
+ bool operator==(const TracingInitArgs& other) const {
+ return std::tie(backends, custom_backend, platform, shmem_size_hint_kb,
+ shmem_page_size_hint_kb, dcheck_is_on_) ==
+ std::tie(other.backends, other.custom_backend, other.platform,
+ other.shmem_size_hint_kb, other.shmem_page_size_hint_kb,
+ other.dcheck_is_on_);
+ }
+
protected:
friend class Tracing;
bool dcheck_is_on_ = PERFETTO_DCHECK_IS_ON();
@@ -84,7 +92,7 @@
class PERFETTO_EXPORT Tracing {
public:
// Initializes Perfetto with the given backends in the calling process and/or
- // with a user-provided backend. Can only be called once.
+ // with a user-provided backend. No-op if called more than once.
static void Initialize(const TracingInitArgs&);
// Start a new tracing session using the given tracing backend. Use
diff --git a/src/tracing/api_integrationtest.cc b/src/tracing/api_integrationtest.cc
index 2d43bf3..c4edec1 100644
--- a/src/tracing/api_integrationtest.cc
+++ b/src/tracing/api_integrationtest.cc
@@ -246,16 +246,13 @@
void SetUp() override {
instance = this;
- // Perfetto can only be initialized once in a process.
- static bool was_initialized;
- if (!was_initialized) {
- perfetto::TracingInitArgs args;
- args.backends = perfetto::kInProcessBackend;
- perfetto::Tracing::Initialize(args);
- was_initialized = true;
- RegisterDataSource<MockDataSource>("my_data_source");
- perfetto::TrackEvent::Register();
- }
+
+ perfetto::TracingInitArgs args;
+ args.backends = perfetto::kInProcessBackend;
+ perfetto::Tracing::Initialize(args);
+ RegisterDataSource<MockDataSource>("my_data_source");
+ perfetto::TrackEvent::Register();
+
// Make sure our data source always has a valid handle.
data_sources_["my_data_source"];
}
diff --git a/src/tracing/tracing.cc b/src/tracing/tracing.cc
index 54d5722..8b20b7f 100644
--- a/src/tracing/tracing.cc
+++ b/src/tracing/tracing.cc
@@ -25,10 +25,20 @@
// static
void Tracing::Initialize(const TracingInitArgs& args) {
+ static bool was_initialized = false;
+ static TracingInitArgs init_args;
+ if (was_initialized) {
+ // Should not be reinitialized with different args.
+ PERFETTO_DCHECK(init_args == args);
+ return;
+ }
+
// Make sure the headers and implementation files agree on the build config.
PERFETTO_CHECK(args.dcheck_is_on_ == PERFETTO_DCHECK_IS_ON());
internal::TracingMuxerImpl::InitializeInstance(args);
internal::TrackRegistry::InitializeInstance();
+ was_initialized = true;
+ init_args = args;
}
// static
diff --git a/src/tracing/track.cc b/src/tracing/track.cc
index 9543c96..b5260e4 100644
--- a/src/tracing/track.cc
+++ b/src/tracing/track.cc
@@ -57,7 +57,10 @@
// static
void TrackRegistry::InitializeInstance() {
- PERFETTO_DCHECK(!instance_);
+ // TODO(eseckler): Chrome may call this more than once. Once Chrome doesn't
+ // call this directly anymore, bring back DCHECK(!instance_) instead.
+ if (instance_)
+ return;
instance_ = new TrackRegistry();
Track::process_uuid = static_cast<uint64_t>(base::Uuidv4().lsb());
}