Merge "client lib: Support initializing multiple times"
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());
 }