Mojo EDK -> Mojo Core / Embedder

The name "EDK" has been pretty widely regarded as meaningless and
therefore confusing to other developers. Given this and the fact
that Mojo is less embedder-centric than it once was and can now be
used without embedding at all, this CL renames the core
implementation to, well, "core".

  - mojo/edk/embedder becomes mojo/core/embedder, and the include path
    now matches the GN target path (finally)
  - mojo/edk/system is moved to mojo/core - all parts of mojo/core
    which are not mojo/core/embedder are private to the core
    implementation
  - mojo::edk -> mojo::core, for both public and private symbols
  - The "EDK" is known as the "Mojo Core Embedder" library
  - Documentation is updated to reflect these changes

A few stub headers have been put in place to allow for incremental
transition from the old things to the new things.

Where absolutely necessary, some forward declarations of
ScopedIPCSupport outside //mojo have been upated too.

Follow-up CLs will migrate everything over to //mojo/core/embedder
etc.

[email protected]
[email protected]
[email protected]
[email protected]
NOPRESUBMIT=true

Bug: None
Cq-Include-Trybots: luci.chromium.try:linux_chromium_dbg_ng
Change-Id: I4f426fa1da67e87184be9eb8e2267160ddb6c2c7
Reviewed-on: https://chromium-review.googlesource.com/1126323
Commit-Queue: Ken Rockot <[email protected]>
Reviewed-by: Ken Rockot <[email protected]>
Cr-Commit-Position: refs/heads/master@{#572627}
diff --git a/mojo/core/handle_table.cc b/mojo/core/handle_table.cc
new file mode 100644
index 0000000..62419a923
--- /dev/null
+++ b/mojo/core/handle_table.cc
@@ -0,0 +1,204 @@
+// Copyright 2014 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 "mojo/core/handle_table.h"
+
+#include <stdint.h>
+
+#include <limits>
+
+#include "base/trace_event/memory_dump_manager.h"
+
+namespace mojo {
+namespace core {
+
+namespace {
+
+const char* GetNameForDispatcherType(Dispatcher::Type type) {
+  switch (type) {
+    case Dispatcher::Type::UNKNOWN:
+      return "unknown";
+    case Dispatcher::Type::MESSAGE_PIPE:
+      return "message_pipe";
+    case Dispatcher::Type::DATA_PIPE_PRODUCER:
+      return "data_pipe_producer";
+    case Dispatcher::Type::DATA_PIPE_CONSUMER:
+      return "data_pipe_consumer";
+    case Dispatcher::Type::SHARED_BUFFER:
+      return "shared_buffer";
+    case Dispatcher::Type::WATCHER:
+      return "watcher";
+    case Dispatcher::Type::PLATFORM_HANDLE:
+      return "platform_handle";
+    case Dispatcher::Type::INVITATION:
+      return "invitation";
+  }
+  NOTREACHED();
+  return "unknown";
+}
+
+}  // namespace
+
+HandleTable::HandleTable() {}
+
+HandleTable::~HandleTable() {}
+
+base::Lock& HandleTable::GetLock() {
+  return lock_;
+}
+
+MojoHandle HandleTable::AddDispatcher(scoped_refptr<Dispatcher> dispatcher) {
+  // Oops, we're out of handles.
+  if (next_available_handle_ == MOJO_HANDLE_INVALID)
+    return MOJO_HANDLE_INVALID;
+
+  MojoHandle handle = next_available_handle_++;
+  auto result =
+      handles_.insert(std::make_pair(handle, Entry(std::move(dispatcher))));
+  DCHECK(result.second);
+
+  return handle;
+}
+
+bool HandleTable::AddDispatchersFromTransit(
+    const std::vector<Dispatcher::DispatcherInTransit>& dispatchers,
+    MojoHandle* handles) {
+  // Oops, we're out of handles.
+  if (next_available_handle_ == MOJO_HANDLE_INVALID)
+    return false;
+
+  DCHECK_LE(dispatchers.size(), std::numeric_limits<uint32_t>::max());
+  // If this insertion would cause handle overflow, we're out of handles.
+  if (next_available_handle_ + dispatchers.size() < next_available_handle_)
+    return false;
+
+  for (size_t i = 0; i < dispatchers.size(); ++i) {
+    MojoHandle handle = MOJO_HANDLE_INVALID;
+    if (dispatchers[i].dispatcher) {
+      handle = next_available_handle_++;
+      auto result = handles_.insert(
+          std::make_pair(handle, Entry(dispatchers[i].dispatcher)));
+      DCHECK(result.second);
+    }
+    handles[i] = handle;
+  }
+
+  return true;
+}
+
+scoped_refptr<Dispatcher> HandleTable::GetDispatcher(MojoHandle handle) const {
+  auto it = handles_.find(handle);
+  if (it == handles_.end())
+    return nullptr;
+  return it->second.dispatcher;
+}
+
+MojoResult HandleTable::GetAndRemoveDispatcher(
+    MojoHandle handle,
+    scoped_refptr<Dispatcher>* dispatcher) {
+  auto it = handles_.find(handle);
+  if (it == handles_.end())
+    return MOJO_RESULT_INVALID_ARGUMENT;
+  if (it->second.busy)
+    return MOJO_RESULT_BUSY;
+
+  *dispatcher = std::move(it->second.dispatcher);
+  handles_.erase(it);
+  return MOJO_RESULT_OK;
+}
+
+MojoResult HandleTable::BeginTransit(
+    const MojoHandle* handles,
+    size_t num_handles,
+    std::vector<Dispatcher::DispatcherInTransit>* dispatchers) {
+  dispatchers->reserve(dispatchers->size() + num_handles);
+  for (size_t i = 0; i < num_handles; ++i) {
+    auto it = handles_.find(handles[i]);
+    if (it == handles_.end())
+      return MOJO_RESULT_INVALID_ARGUMENT;
+    if (it->second.busy)
+      return MOJO_RESULT_BUSY;
+
+    Dispatcher::DispatcherInTransit d;
+    d.local_handle = handles[i];
+    d.dispatcher = it->second.dispatcher;
+    if (!d.dispatcher->BeginTransit())
+      return MOJO_RESULT_BUSY;
+    it->second.busy = true;
+    dispatchers->push_back(d);
+  }
+  return MOJO_RESULT_OK;
+}
+
+void HandleTable::CompleteTransitAndClose(
+    const std::vector<Dispatcher::DispatcherInTransit>& dispatchers) {
+  for (const auto& dispatcher : dispatchers) {
+    auto it = handles_.find(dispatcher.local_handle);
+    DCHECK(it != handles_.end() && it->second.busy);
+    handles_.erase(it);
+    dispatcher.dispatcher->CompleteTransitAndClose();
+  }
+}
+
+void HandleTable::CancelTransit(
+    const std::vector<Dispatcher::DispatcherInTransit>& dispatchers) {
+  for (const auto& dispatcher : dispatchers) {
+    auto it = handles_.find(dispatcher.local_handle);
+    DCHECK(it != handles_.end() && it->second.busy);
+    it->second.busy = false;
+    dispatcher.dispatcher->CancelTransit();
+  }
+}
+
+void HandleTable::GetActiveHandlesForTest(std::vector<MojoHandle>* handles) {
+  handles->clear();
+  for (const auto& entry : handles_)
+    handles->push_back(entry.first);
+}
+
+// MemoryDumpProvider implementation.
+bool HandleTable::OnMemoryDump(const base::trace_event::MemoryDumpArgs& args,
+                               base::trace_event::ProcessMemoryDump* pmd) {
+  // Create entries for all relevant dispatcher types to ensure they are present
+  // in the final dump.
+  std::map<Dispatcher::Type, int> handle_count;
+  handle_count[Dispatcher::Type::MESSAGE_PIPE];
+  handle_count[Dispatcher::Type::DATA_PIPE_PRODUCER];
+  handle_count[Dispatcher::Type::DATA_PIPE_CONSUMER];
+  handle_count[Dispatcher::Type::SHARED_BUFFER];
+  handle_count[Dispatcher::Type::WATCHER];
+  handle_count[Dispatcher::Type::PLATFORM_HANDLE];
+  handle_count[Dispatcher::Type::INVITATION];
+
+  // Count the number of each dispatcher type.
+  {
+    base::AutoLock lock(GetLock());
+    for (const auto& entry : handles_) {
+      ++handle_count[entry.second.dispatcher->GetType()];
+    }
+  }
+
+  for (const auto& entry : handle_count) {
+    base::trace_event::MemoryAllocatorDump* inner_dump =
+        pmd->CreateAllocatorDump(std::string("mojo/") +
+                                 GetNameForDispatcherType(entry.first));
+    inner_dump->AddScalar(
+        base::trace_event::MemoryAllocatorDump::kNameObjectCount,
+        base::trace_event::MemoryAllocatorDump::kUnitsObjects, entry.second);
+  }
+
+  return true;
+}
+
+HandleTable::Entry::Entry() {}
+
+HandleTable::Entry::Entry(scoped_refptr<Dispatcher> dispatcher)
+    : dispatcher(std::move(dispatcher)) {}
+
+HandleTable::Entry::Entry(const Entry& other) = default;
+
+HandleTable::Entry::~Entry() {}
+
+}  // namespace core
+}  // namespace mojo