| 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
|
|
|