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