Index: services/blamer/public/cpp/blamer_interface.cc |
diff --git a/services/blamer/public/cpp/blamer_interface.cc b/services/blamer/public/cpp/blamer_interface.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..53618ff703240e19a1e0487f02142a109e239118 |
--- /dev/null |
+++ b/services/blamer/public/cpp/blamer_interface.cc |
@@ -0,0 +1,74 @@ |
+// Copyright 2017 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. |
+ |
+#include "services/blamer/public/cpp/blamer_interface.h" |
+ |
+#include <atomic> |
+ |
+#include "services/blamer/public/interfaces/service_constants.mojom.h" |
+#include "services/blamer/shared_memory_heap.h" |
+ |
+namespace blamer { |
+ |
+namespace { |
+ |
+void OnConnectionError() { |
+ // The service should outlast child processes. |
+ NOTREACHED(); |
+} |
+ |
+// Used to indicate that the right to create the singleton instance has been |
+// acquired. |
+BlamerInterface* kInstanceLockSentinel = reinterpret_cast<BlamerInterface*>(1); |
+ |
+std::atomic<BlamerInterface*> g_instance(nullptr); |
+ |
+} // namespace |
+ |
+BlamerInterface::~BlamerInterface() = default; |
+ |
+BlamerInterface* BlamerInterface::CreateForProcess( |
+ service_manager::Connector* connector) { |
+ BlamerInterface* instance = g_instance.load(); |
+ if (instance != nullptr && instance != kInstanceLockSentinel) |
+ return instance; |
+ |
+ // Try to acquire the right to create the singleton. |
+ if (instance == nullptr && |
+ g_instance.compare_exchange_strong(instance, kInstanceLockSentinel)) { |
+ instance = new BlamerInterface(connector); |
+ BlamerInterface* expected = kInstanceLockSentinel; |
+ CHECK(g_instance.compare_exchange_strong(expected, instance)); |
+ return instance; |
+ } |
+ |
+ // Getting here means somebody else has the right to create the singleton. |
+ // Wait until it's available. |
+ while (true) { |
+ instance = g_instance.load(); |
+ if (instance != nullptr && instance != kInstanceLockSentinel) |
+ return instance; |
+ } |
+} |
+ |
+BlamerInterface* BlamerInterface::GetForProcess() { |
+ BlamerInterface* instance = g_instance.load(); |
+ if (instance == kInstanceLockSentinel) |
+ return nullptr; |
+ return instance; |
+} |
+ |
+BlamerInterface::BlamerInterface(service_manager::Connector* connector) |
+ : shared_memory_heap_(nullptr) { |
+ mojom::SharedMemoryHeapRegistryPtr heap_registry; |
+ connector->BindInterface(mojom::kServiceName, |
+ mojo::MakeRequest(&heap_registry)); |
+ heap_registry.set_connection_error_handler(base::Bind( |
+ &OnConnectionError)); |
+ |
+ // Create a shared memory heap for this process. |
+ shared_memory_heap_.reset(new SharedMemoryHeap(std::move(heap_registry))); |
+} |
+ |
+} // namespace blamer |