summaryrefslogtreecommitdiffstats
path: root/chromium/mojo/public/cpp
diff options
context:
space:
mode:
authorJocelyn Turcotte <jocelyn.turcotte@digia.com>2014-08-08 14:30:41 +0200
committerJocelyn Turcotte <jocelyn.turcotte@digia.com>2014-08-12 13:49:54 +0200
commitab0a50979b9eb4dfa3320eff7e187e41efedf7a9 (patch)
tree498dfb8a97ff3361a9f7486863a52bb4e26bb898 /chromium/mojo/public/cpp
parent4ce69f7403811819800e7c5ae1318b2647e778d1 (diff)
Update Chromium to beta version 37.0.2062.68
Change-Id: I188e3b5aff1bec75566014291b654eb19f5bc8ca Reviewed-by: Andras Becsi <andras.becsi@digia.com>
Diffstat (limited to 'chromium/mojo/public/cpp')
-rw-r--r--chromium/mojo/public/cpp/DEPS18
-rw-r--r--chromium/mojo/public/cpp/README.md71
-rw-r--r--chromium/mojo/public/cpp/application/DEPS14
-rw-r--r--chromium/mojo/public/cpp/application/application.h121
-rw-r--r--chromium/mojo/public/cpp/application/connect.h24
-rw-r--r--chromium/mojo/public/cpp/application/lib/application.cc34
-rw-r--r--chromium/mojo/public/cpp/application/lib/mojo_main_chromium.cc23
-rw-r--r--chromium/mojo/public/cpp/application/lib/mojo_main_standalone.cc22
-rw-r--r--chromium/mojo/public/cpp/application/lib/service_connector.cc18
-rw-r--r--chromium/mojo/public/cpp/application/lib/service_connector.h133
-rw-r--r--chromium/mojo/public/cpp/application/lib/service_registry.cc78
-rw-r--r--chromium/mojo/public/cpp/application/lib/service_registry.h55
-rw-r--r--chromium/mojo/public/cpp/bindings/BUILD.gn53
-rw-r--r--chromium/mojo/public/cpp/bindings/DEPS3
-rw-r--r--chromium/mojo/public/cpp/bindings/array.h143
-rw-r--r--chromium/mojo/public/cpp/bindings/callback.h462
-rw-r--r--chromium/mojo/public/cpp/bindings/callback.h.pump80
-rw-r--r--chromium/mojo/public/cpp/bindings/error_handler.h19
-rw-r--r--chromium/mojo/public/cpp/bindings/interface_impl.h109
-rw-r--r--chromium/mojo/public/cpp/bindings/interface_ptr.h124
-rw-r--r--chromium/mojo/public/cpp/bindings/interface_request.h76
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/DEPS5
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/TODO6
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/array_internal.cc70
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/array_internal.h384
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/array_serialization.h179
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/bindings_internal.h86
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/bindings_serialization.cc118
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/bindings_serialization.h83
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/bounds_checker.cc77
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/bounds_checker.h64
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/buffer.h24
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/callback_internal.h26
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/connector.cc157
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/connector.h100
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/filter_chain.cc49
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/filter_chain.h66
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/fixed_buffer.cc53
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/fixed_buffer.h67
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/interface_impl_internal.h94
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/interface_ptr_internal.h84
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/message.cc81
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/message_builder.cc52
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/message_builder.h63
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/message_filter.cc23
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/message_header_validator.cc81
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/message_header_validator.h24
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/message_internal.h44
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/message_queue.cc50
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/message_queue.h47
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/no_interface.cc20
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/router.cc140
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/router.h91
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/shared_data.h84
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/shared_ptr.h63
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/string_serialization.cc38
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/string_serialization.h20
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/sync_dispatcher.cc27
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/template_util.h89
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/validation_errors.cc64
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/validation_errors.h66
-rw-r--r--chromium/mojo/public/cpp/bindings/message.h123
-rw-r--r--chromium/mojo/public/cpp/bindings/message_filter.h39
-rw-r--r--chromium/mojo/public/cpp/bindings/no_interface.h56
-rw-r--r--chromium/mojo/public/cpp/bindings/string.h154
-rw-r--r--chromium/mojo/public/cpp/bindings/struct_ptr.h154
-rw-r--r--chromium/mojo/public/cpp/bindings/sync_dispatcher.h47
-rw-r--r--chromium/mojo/public/cpp/bindings/type_converter.h82
-rw-r--r--chromium/mojo/public/cpp/environment/environment.h41
-rw-r--r--chromium/mojo/public/cpp/environment/lib/DEPS4
-rw-r--r--chromium/mojo/public/cpp/environment/lib/default_async_waiter.cc94
-rw-r--r--chromium/mojo/public/cpp/environment/lib/default_async_waiter.h18
-rw-r--r--chromium/mojo/public/cpp/environment/lib/default_logger.cc71
-rw-r--r--chromium/mojo/public/cpp/environment/lib/default_logger.h18
-rw-r--r--chromium/mojo/public/cpp/environment/lib/environment.cc60
-rw-r--r--chromium/mojo/public/cpp/environment/lib/logging.cc45
-rw-r--r--chromium/mojo/public/cpp/environment/logging.h87
-rw-r--r--chromium/mojo/public/cpp/gles2/DEPS4
-rw-r--r--chromium/mojo/public/cpp/gles2/gles2.h24
-rw-r--r--chromium/mojo/public/cpp/system/core.h555
-rw-r--r--chromium/mojo/public/cpp/system/macros.h53
-rw-r--r--chromium/mojo/public/cpp/test_support/DEPS3
-rw-r--r--chromium/mojo/public/cpp/test_support/lib/test_support.cc26
-rw-r--r--chromium/mojo/public/cpp/test_support/lib/test_utils.cc91
-rw-r--r--chromium/mojo/public/cpp/test_support/test_support.h34
-rw-r--r--chromium/mojo/public/cpp/test_support/test_utils.h39
-rw-r--r--chromium/mojo/public/cpp/utility/lib/mutex.cc52
-rw-r--r--chromium/mojo/public/cpp/utility/lib/run_loop.cc221
-rw-r--r--chromium/mojo/public/cpp/utility/lib/thread.cc69
-rw-r--r--chromium/mojo/public/cpp/utility/lib/thread_local.h61
-rw-r--r--chromium/mojo/public/cpp/utility/lib/thread_local_posix.cc39
-rw-r--r--chromium/mojo/public/cpp/utility/lib/thread_local_win.cc39
-rw-r--r--chromium/mojo/public/cpp/utility/mutex.h70
-rw-r--r--chromium/mojo/public/cpp/utility/run_loop.h108
-rw-r--r--chromium/mojo/public/cpp/utility/run_loop_handler.h25
-rw-r--r--chromium/mojo/public/cpp/utility/thread.h62
96 files changed, 7307 insertions, 0 deletions
diff --git a/chromium/mojo/public/cpp/DEPS b/chromium/mojo/public/cpp/DEPS
new file mode 100644
index 00000000000..74acd7c7ed3
--- /dev/null
+++ b/chromium/mojo/public/cpp/DEPS
@@ -0,0 +1,18 @@
+include_rules = [
+ # Require explicit dependencies in each directory.
+ "-mojo/public",
+ # But everyone can depend on the C and C++ system headers.
+ "+mojo/public/c/system",
+ "+mojo/public/cpp/system",
+ # Ditto for the C environment headers (but not the C++ environment, since it
+ # has dependencies of its own).
+ "+mojo/public/c/environment",
+]
+
+specific_include_rules = {
+ r".*_(unit|perf)test\.cc": [
+ "+testing",
+ "+mojo/public/cpp/test_support",
+ "+mojo/public/cpp/utility",
+ ],
+}
diff --git a/chromium/mojo/public/cpp/README.md b/chromium/mojo/public/cpp/README.md
new file mode 100644
index 00000000000..8f03d984b9a
--- /dev/null
+++ b/chromium/mojo/public/cpp/README.md
@@ -0,0 +1,71 @@
+Mojo Public C++ API
+===================
+
+This directory contains C++ language bindings for the Mojo Public API.
+
+A number of subdirectories provide wrappers for the lower-level C APIs (in
+subdirectories of the same name, under mojo/public/c/). Typically, these
+wrappers provide increased convenience and/or type-safety.
+
+Other subdirectories provide support (static) libraries of various sorts. In
+this case, the organization is to have the public interface for the library in
+defined in header files in the subdirectory itself and the implementation of the
+library at a lower level, under a lib (sub)subdirectory. A developer should be
+able to substitute their own implementation of any such support library, and
+expect other support libraries, which may depend on that library, to work
+properly.
+
+Bindings
+--------
+
+The bindings/ subdirectory contains a support (static) library needed by the
+code generated by the bindings generator tool (in mojo/public/tools/bindings/),
+which translates Mojo IDL (.mojom) files into idiomatic C++ (among other
+languages).
+
+This library depends on the Environment library.
+
+Environment
+-----------
+
+The environment/ subdirectory contains a support (static) library that
+represents shared state needed to support the Bindings and GLES2 libraries.
+
+This library depends on the Utility library.
+
+
+GLES2
+-----
+
+The gles2/ subdirectory contains C++ wrappers (and some additional helpers) of
+the API defined in mojo/public/c/gles2/ (which provides access to GLES2).
+
+These wrappers depend on the Environment library.
+
+Shell
+-----
+
+The shell/ subdirectory contains a support (static) library that aids in writing
+Mojo applications and interacting with the Shell service.
+
+System
+------
+
+The system/ subdirectory contains C++ wrappers (and some additional helpers) of
+the API defined in mojo/public/c/system/, which defines the basic, "core" API,
+especially used to communicate with Mojo services.
+
+Test Support
+------------
+
+The test_support/ subdirectory contains C++ wrappers of the test-only API
+defined in mojo/public/c/test_support/. It is not meant for general use by Mojo
+applications.
+
+Utility
+-------
+
+The utility/ subdirectory contains a support (static) library that provides
+various basic functionality. Most notably, it provides an implementation of a
+RunLoop based on MojoWaitMany() that applications may use as the basis for
+asynchronous message processing.
diff --git a/chromium/mojo/public/cpp/application/DEPS b/chromium/mojo/public/cpp/application/DEPS
new file mode 100644
index 00000000000..e808b79707e
--- /dev/null
+++ b/chromium/mojo/public/cpp/application/DEPS
@@ -0,0 +1,14 @@
+include_rules = [
+ "+mojo/public/cpp/bindings",
+ "+mojo/public/interfaces/service_provider",
+]
+
+specific_include_rules = {
+ "mojo_main_chromium.cc": [
+ "+base",
+ "+mojo/public/cpp"
+ ],
+ "mojo_main_standalone.cc": [
+ "+mojo/public/cpp"
+ ],
+}
diff --git a/chromium/mojo/public/cpp/application/application.h b/chromium/mojo/public/cpp/application/application.h
new file mode 100644
index 00000000000..da7a0ed7c61
--- /dev/null
+++ b/chromium/mojo/public/cpp/application/application.h
@@ -0,0 +1,121 @@
+// 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.
+
+#ifndef MOJO_PUBLIC_APPLICATION_APPLICATION_H_
+#define MOJO_PUBLIC_APPLICATION_APPLICATION_H_
+#include <vector>
+
+#include "mojo/public/cpp/application/connect.h"
+#include "mojo/public/cpp/application/lib/service_connector.h"
+#include "mojo/public/cpp/system/core.h"
+#include "mojo/public/interfaces/service_provider/service_provider.mojom.h"
+
+#if defined(WIN32)
+#if !defined(CDECL)
+#define CDECL __cdecl
+#endif
+#define APPLICATION_EXPORT __declspec(dllexport)
+#else
+#define CDECL
+#define APPLICATION_EXPORT __attribute__((visibility("default")))
+#endif
+
+// DSOs can either implement MojoMain directly or include
+// mojo_main_{standalone|chromium}.cc in their project and implement
+// Application::Create();
+// TODO(davemoore): Establish this as part of our SDK for third party mojo
+// application writers.
+extern "C" APPLICATION_EXPORT MojoResult CDECL MojoMain(
+ MojoHandle service_provider_handle);
+
+namespace mojo {
+
+// Utility class for creating ServiceProviders that vend service instances.
+// To use define a class that implements your specific server api, e.g. FooImpl
+// to implement a service named Foo.
+// That class must subclass an InterfaceImpl specialization.
+//
+// If there is context that is to be shared amongst all instances, define a
+// constructor with that class as its only argument, otherwise define an empty
+// constructor.
+//
+// class FooImpl : public InterfaceImpl<Foo> {
+// public:
+// FooImpl() {}
+// };
+//
+// or
+//
+// class BarImpl : public InterfaceImpl<Bar> {
+// public:
+// // context will remain valid for the lifetime of BarImpl.
+// BarImpl(BarContext* context) : context_(context) {}
+// private:
+// BarContext* context;
+// };
+//
+// Create an Application instance that collects any service implementations.
+//
+// Application app(service_provider_handle);
+// app.AddService<FooImpl>();
+//
+// BarContext context;
+// app.AddService<BarImpl>(&context);
+//
+//
+class Application {
+ public:
+ Application();
+ explicit Application(ScopedMessagePipeHandle service_provider_handle);
+ explicit Application(MojoHandle service_provider_handle);
+ virtual ~Application();
+
+ // Override this method to control what urls are allowed to connect to a
+ // service.
+ virtual bool AllowIncomingConnection(const mojo::String& service_name,
+ const mojo::String& requestor_url);
+
+ template <typename Impl, typename Context>
+ void AddService(Context* context) {
+ service_registry_.AddServiceConnector(
+ new internal::ServiceConnector<Impl, Context>(Impl::Name_, context));
+ }
+
+ template <typename Impl>
+ void AddService() {
+ service_registry_.AddServiceConnector(
+ new internal::ServiceConnector<Impl, void>(Impl::Name_, NULL));
+ }
+
+ template <typename Interface>
+ void ConnectTo(const std::string& url, InterfacePtr<Interface>* ptr) {
+ mojo::ConnectToService(service_provider(), url, ptr);
+ }
+
+ ServiceProvider* service_provider() {
+ return service_registry_.remote_service_provider();
+ }
+
+ void BindServiceProvider(ScopedMessagePipeHandle service_provider_handle);
+
+ protected:
+ // Override this to do any necessary initialization. There's no need to call
+ // Application's implementation.
+ // The service_provider will be bound to its pipe before this is called.
+ virtual void Initialize();
+
+ private:
+ friend MojoResult (::MojoMain)(MojoHandle);
+
+ // Implement this method to create the specific subclass of Application.
+ static Application* Create();
+
+ internal::ServiceRegistry service_registry_;
+
+ MOJO_DISALLOW_COPY_AND_ASSIGN(Application);
+};
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_APPLICATION_APPLICATION_H_
diff --git a/chromium/mojo/public/cpp/application/connect.h b/chromium/mojo/public/cpp/application/connect.h
new file mode 100644
index 00000000000..e4ba641e2ed
--- /dev/null
+++ b/chromium/mojo/public/cpp/application/connect.h
@@ -0,0 +1,24 @@
+// 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.
+
+#ifndef MOJO_PUBLIC_CPP_APPLICATION_CONNECT_H_
+#define MOJO_PUBLIC_CPP_APPLICATION_CONNECT_H_
+
+#include "mojo/public/interfaces/service_provider/service_provider.mojom.h"
+
+namespace mojo {
+
+template <typename Interface>
+inline void ConnectToService(ServiceProvider* service_provider,
+ const std::string& url,
+ InterfacePtr<Interface>* ptr) {
+ MessagePipe pipe;
+ ptr->Bind(pipe.handle0.Pass());
+ service_provider->ConnectToService(
+ url, Interface::Name_, pipe.handle1.Pass(), std::string());
+}
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_APPLICATION_CONNECT_H_
diff --git a/chromium/mojo/public/cpp/application/lib/application.cc b/chromium/mojo/public/cpp/application/lib/application.cc
new file mode 100644
index 00000000000..78f5a8bbd0e
--- /dev/null
+++ b/chromium/mojo/public/cpp/application/lib/application.cc
@@ -0,0 +1,34 @@
+// 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/public/cpp/application/application.h"
+
+namespace mojo {
+
+Application::Application() : service_registry_(this) {}
+
+Application::Application(ScopedMessagePipeHandle service_provider_handle)
+ : service_registry_(this, service_provider_handle.Pass()) {}
+
+Application::Application(MojoHandle service_provider_handle)
+ : service_registry_(
+ this,
+ mojo::MakeScopedHandle(
+ MessagePipeHandle(service_provider_handle)).Pass()) {}
+
+Application::~Application() {}
+
+bool Application::AllowIncomingConnection(const mojo::String& service_name,
+ const mojo::String& requestor_url) {
+ return true;
+}
+
+void Application::BindServiceProvider(
+ ScopedMessagePipeHandle service_provider_handle) {
+ service_registry_.BindRemoteServiceProvider(service_provider_handle.Pass());
+}
+
+void Application::Initialize() {}
+
+} // namespace mojo
diff --git a/chromium/mojo/public/cpp/application/lib/mojo_main_chromium.cc b/chromium/mojo/public/cpp/application/lib/mojo_main_chromium.cc
new file mode 100644
index 00000000000..cda7cd02d18
--- /dev/null
+++ b/chromium/mojo/public/cpp/application/lib/mojo_main_chromium.cc
@@ -0,0 +1,23 @@
+// 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 "base/at_exit.h"
+#include "base/command_line.h"
+#include "base/message_loop/message_loop.h"
+#include "mojo/public/cpp/application/application.h"
+
+extern "C" APPLICATION_EXPORT MojoResult CDECL MojoMain(
+ MojoHandle service_provider_handle) {
+ base::CommandLine::Init(0, NULL);
+ base::AtExitManager at_exit;
+ base::MessageLoop loop;
+
+ scoped_ptr<mojo::Application> app(mojo::Application::Create());
+ app->BindServiceProvider(
+ mojo::MakeScopedHandle(mojo::MessagePipeHandle(service_provider_handle)));
+ app->Initialize();
+ loop.Run();
+
+ return MOJO_RESULT_OK;
+}
diff --git a/chromium/mojo/public/cpp/application/lib/mojo_main_standalone.cc b/chromium/mojo/public/cpp/application/lib/mojo_main_standalone.cc
new file mode 100644
index 00000000000..05825aa3319
--- /dev/null
+++ b/chromium/mojo/public/cpp/application/lib/mojo_main_standalone.cc
@@ -0,0 +1,22 @@
+// 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/public/cpp/application/application.h"
+#include "mojo/public/cpp/environment/environment.h"
+#include "mojo/public/cpp/utility/run_loop.h"
+
+extern "C" APPLICATION_EXPORT MojoResult CDECL MojoMain(
+ MojoHandle service_provider_handle) {
+ mojo::Environment env;
+ mojo::RunLoop loop;
+
+ mojo::Application* app = mojo::Application::Create();
+ app->BindServiceProvider(
+ mojo::MakeScopedHandle(mojo::MessagePipeHandle(service_provider_handle)));
+ app->Initialize();
+ loop.Run();
+ delete app;
+
+ return MOJO_RESULT_OK;
+}
diff --git a/chromium/mojo/public/cpp/application/lib/service_connector.cc b/chromium/mojo/public/cpp/application/lib/service_connector.cc
new file mode 100644
index 00000000000..5cc4421b7aa
--- /dev/null
+++ b/chromium/mojo/public/cpp/application/lib/service_connector.cc
@@ -0,0 +1,18 @@
+// 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/public/cpp/application/lib/service_connector.h"
+
+namespace mojo {
+namespace internal {
+
+ServiceConnectorBase::ServiceConnectorBase(const std::string& name)
+ : name_(name),
+ registry_(NULL) {
+}
+
+ServiceConnectorBase::~ServiceConnectorBase() {}
+
+} // namespace internal
+} // namespace mojo
diff --git a/chromium/mojo/public/cpp/application/lib/service_connector.h b/chromium/mojo/public/cpp/application/lib/service_connector.h
new file mode 100644
index 00000000000..30786adb55d
--- /dev/null
+++ b/chromium/mojo/public/cpp/application/lib/service_connector.h
@@ -0,0 +1,133 @@
+// 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.
+
+#ifndef MOJO_PUBLIC_CPP_APPLICATION_LIB_SERVICE_CONNECTOR_H_
+#define MOJO_PUBLIC_CPP_APPLICATION_LIB_SERVICE_CONNECTOR_H_
+
+#include <assert.h>
+
+#include <vector>
+
+#include "mojo/public/cpp/application/lib/service_registry.h"
+#include "mojo/public/interfaces/service_provider/service_provider.mojom.h"
+
+namespace mojo {
+namespace internal {
+
+template <class ServiceImpl, typename Context>
+class ServiceConnector;
+
+// Specialization of ServiceConnection.
+// ServiceImpl: Subclass of InterfaceImpl<...>.
+// Context: Type of shared context.
+template <class ServiceImpl, typename Context>
+class ServiceConnection : public ServiceImpl {
+ public:
+ ServiceConnection() : ServiceImpl() {}
+ ServiceConnection(Context* context) : ServiceImpl(context) {}
+
+ virtual void OnConnectionError() MOJO_OVERRIDE {
+ service_connector_->RemoveConnection(static_cast<ServiceImpl*>(this));
+ ServiceImpl::OnConnectionError();
+ }
+
+private:
+ friend class ServiceConnector<ServiceImpl, Context>;
+
+ // Called shortly after this class is instantiated.
+ void set_service_connector(
+ ServiceConnector<ServiceImpl, Context>* connector) {
+ service_connector_ = connector;
+ }
+
+ ServiceConnector<ServiceImpl, Context>* service_connector_;
+
+ MOJO_DISALLOW_COPY_AND_ASSIGN(ServiceConnection);
+};
+
+template <typename ServiceImpl, typename Context>
+struct ServiceConstructor {
+ static ServiceConnection<ServiceImpl, Context>* New(Context* context) {
+ return new ServiceConnection<ServiceImpl, Context>(context);
+ }
+};
+
+template <typename ServiceImpl>
+struct ServiceConstructor<ServiceImpl, void> {
+ public:
+ static ServiceConnection<ServiceImpl, void>* New(void* context) {
+ return new ServiceConnection<ServiceImpl, void>();
+ }
+};
+
+class ServiceConnectorBase {
+ public:
+ ServiceConnectorBase(const std::string& name);
+ virtual ~ServiceConnectorBase();
+ virtual void ConnectToService(const std::string& url,
+ const std::string& name,
+ ScopedMessagePipeHandle client_handle) = 0;
+ std::string name() const { return name_; }
+ void set_registry(ServiceRegistry* registry) { registry_ = registry; }
+
+ protected:
+ std::string name_;
+ ServiceRegistry* registry_;
+
+ MOJO_DISALLOW_COPY_AND_ASSIGN(ServiceConnectorBase);
+};
+
+template <class ServiceImpl, typename Context=void>
+class ServiceConnector : public internal::ServiceConnectorBase {
+ public:
+ ServiceConnector(const std::string& name, Context* context = NULL)
+ : ServiceConnectorBase(name), context_(context) {}
+
+ virtual ~ServiceConnector() {
+ ConnectionList doomed;
+ doomed.swap(connections_);
+ for (typename ConnectionList::iterator it = doomed.begin();
+ it != doomed.end(); ++it) {
+ delete *it;
+ }
+ assert(connections_.empty()); // No one should have added more!
+ }
+
+ virtual void ConnectToService(const std::string& url,
+ const std::string& name,
+ ScopedMessagePipeHandle handle) MOJO_OVERRIDE {
+ ServiceConnection<ServiceImpl, Context>* impl =
+ ServiceConstructor<ServiceImpl, Context>::New(context_);
+ impl->set_service_connector(this);
+ BindToPipe(impl, handle.Pass());
+
+ connections_.push_back(impl);
+ }
+
+ void RemoveConnection(ServiceImpl* impl) {
+ // Called from ~ServiceImpl, in response to a connection error.
+ for (typename ConnectionList::iterator it = connections_.begin();
+ it != connections_.end(); ++it) {
+ if (*it == impl) {
+ delete impl;
+ connections_.erase(it);
+ return;
+ }
+ }
+ }
+
+ Context* context() const { return context_; }
+
+ private:
+ typedef std::vector<ServiceImpl*> ConnectionList;
+ ConnectionList connections_;
+ Context* context_;
+
+ MOJO_DISALLOW_COPY_AND_ASSIGN(ServiceConnector);
+};
+
+} // namespace internal
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_APPLICATION_LIB_SERVICE_CONNECTOR_H_
diff --git a/chromium/mojo/public/cpp/application/lib/service_registry.cc b/chromium/mojo/public/cpp/application/lib/service_registry.cc
new file mode 100644
index 00000000000..bc901dfb924
--- /dev/null
+++ b/chromium/mojo/public/cpp/application/lib/service_registry.cc
@@ -0,0 +1,78 @@
+// 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/public/cpp/application/lib/service_registry.h"
+
+#include "mojo/public/cpp/application/application.h"
+#include "mojo/public/cpp/application/lib/service_connector.h"
+
+namespace mojo {
+namespace internal {
+
+ServiceRegistry::ServiceRegistry(Application* application)
+ : application_(application) {
+}
+
+ServiceRegistry::ServiceRegistry(
+ Application* application,
+ ScopedMessagePipeHandle service_provider_handle)
+ : application_(application) {
+ remote_service_provider_.Bind(service_provider_handle.Pass());
+ remote_service_provider_.set_client(this);
+}
+
+ServiceRegistry::~ServiceRegistry() {
+ for (NameToServiceConnectorMap::iterator i =
+ name_to_service_connector_.begin();
+ i != name_to_service_connector_.end(); ++i) {
+ delete i->second;
+ }
+ name_to_service_connector_.clear();
+}
+
+void ServiceRegistry::AddServiceConnector(
+ ServiceConnectorBase* service_connector) {
+ name_to_service_connector_[service_connector->name()] = service_connector;
+ service_connector->set_registry(this);
+}
+
+void ServiceRegistry::RemoveServiceConnector(
+ ServiceConnectorBase* service_connector) {
+ NameToServiceConnectorMap::iterator it =
+ name_to_service_connector_.find(service_connector->name());
+ assert(it != name_to_service_connector_.end());
+ delete it->second;
+ name_to_service_connector_.erase(it);
+ if (name_to_service_connector_.empty())
+ remote_service_provider_.reset();
+}
+
+void ServiceRegistry::BindRemoteServiceProvider(
+ ScopedMessagePipeHandle service_provider_handle) {
+ remote_service_provider_.Bind(service_provider_handle.Pass());
+ remote_service_provider_.set_client(this);
+}
+
+void ServiceRegistry::ConnectToService(const mojo::String& service_url,
+ const mojo::String& service_name,
+ ScopedMessagePipeHandle client_handle,
+ const mojo::String& requestor_url) {
+ if (name_to_service_connector_.find(service_name) ==
+ name_to_service_connector_.end() ||
+ !application_->AllowIncomingConnection(service_name, requestor_url)) {
+ client_handle.reset();
+ return;
+ }
+
+ internal::ServiceConnectorBase* service_connector =
+ name_to_service_connector_[service_name];
+ assert(service_connector);
+ // requestor_url is ignored because the service_connector stores the url
+ // of the requestor safely.
+ return service_connector->ConnectToService(
+ service_url, service_name, client_handle.Pass());
+}
+
+} // namespace internal
+} // namespace mojo
diff --git a/chromium/mojo/public/cpp/application/lib/service_registry.h b/chromium/mojo/public/cpp/application/lib/service_registry.h
new file mode 100644
index 00000000000..478cd055ef2
--- /dev/null
+++ b/chromium/mojo/public/cpp/application/lib/service_registry.h
@@ -0,0 +1,55 @@
+// 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.
+
+#ifndef MOJO_PUBLIC_CPP_APPLICATION_LIB_SERVICE_REGISTRY_H_
+#define MOJO_PUBLIC_CPP_APPLICATION_LIB_SERVICE_REGISTRY_H_
+
+#include "mojo/public/interfaces/service_provider/service_provider.mojom.h"
+
+namespace mojo {
+
+class Application;
+
+namespace internal {
+
+class ServiceConnectorBase;
+
+class ServiceRegistry : public ServiceProvider {
+ public:
+ ServiceRegistry(Application* application);
+ ServiceRegistry(Application* application,
+ ScopedMessagePipeHandle service_provider_handle);
+ virtual ~ServiceRegistry();
+
+ void AddServiceConnector(ServiceConnectorBase* service_connector);
+ void RemoveServiceConnector(ServiceConnectorBase* service_connector);
+
+ ServiceProvider* remote_service_provider() {
+ return remote_service_provider_.get();
+ }
+
+ void BindRemoteServiceProvider(
+ ScopedMessagePipeHandle service_provider_handle);
+
+ // ServiceProvider method.
+ virtual void ConnectToService(const mojo::String& service_url,
+ const mojo::String& service_name,
+ ScopedMessagePipeHandle client_handle,
+ const mojo::String& requestor_url)
+ MOJO_OVERRIDE;
+
+ private:
+ Application* application_;
+ typedef std::map<std::string, ServiceConnectorBase*>
+ NameToServiceConnectorMap;
+ NameToServiceConnectorMap name_to_service_connector_;
+ ServiceProviderPtr remote_service_provider_;
+
+ MOJO_DISALLOW_COPY_AND_ASSIGN(ServiceRegistry);
+};
+
+} // namespace internal
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_APPLICATION_LIB_SERVICE_REGISTRY_H_
diff --git a/chromium/mojo/public/cpp/bindings/BUILD.gn b/chromium/mojo/public/cpp/bindings/BUILD.gn
new file mode 100644
index 00000000000..2cc35aa52ff
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/BUILD.gn
@@ -0,0 +1,53 @@
+# 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.
+
+source_set("bindings") {
+ sources = [
+ "array.h",
+ "callback.h",
+ "error_handler.h",
+ "interface_ptr.h",
+ "message.h",
+ "message_filter.h",
+ "no_interface.h",
+ "string.h",
+ "struct_ptr.h",
+ "sync_dispatcher.h",
+ "type_converter.h",
+ "lib/array_internal.cc",
+ "lib/array_internal.h",
+ "lib/array_serialization.h",
+ "lib/bindings_internal.h",
+ "lib/bindings_serialization.cc",
+ "lib/bindings_serialization.h",
+ "lib/bounds_checker.cc",
+ "lib/bounds_checker.h",
+ "lib/buffer.h",
+ "lib/callback_internal.h",
+ "lib/connector.cc",
+ "lib/connector.h",
+ "lib/filter_chain.cc",
+ "lib/filter_chain.h",
+ "lib/fixed_buffer.cc",
+ "lib/fixed_buffer.h",
+ "lib/message.cc",
+ "lib/message_builder.cc",
+ "lib/message_builder.h",
+ "lib/message_filter.cc",
+ "lib/message_internal.h",
+ "lib/message_queue.cc",
+ "lib/message_queue.h",
+ "lib/no_interface.cc",
+ "lib/router.cc",
+ "lib/router.h",
+ "lib/shared_data.h",
+ "lib/shared_ptr.h",
+ "lib/string_serialization.cc",
+ "lib/string_serialization.h",
+ "lib/sync_dispatcher.cc",
+ "lib/template_util.h",
+ "lib/validation_errors.cc",
+ "lib/validation_errors.h",
+ ]
+}
diff --git a/chromium/mojo/public/cpp/bindings/DEPS b/chromium/mojo/public/cpp/bindings/DEPS
new file mode 100644
index 00000000000..2a0496e9d9c
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+ "+mojo/public/cpp/environment",
+]
diff --git a/chromium/mojo/public/cpp/bindings/array.h b/chromium/mojo/public/cpp/bindings/array.h
new file mode 100644
index 00000000000..daf7125bb3c
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/array.h
@@ -0,0 +1,143 @@
+// Copyright 2013 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.
+
+#ifndef MOJO_PUBLIC_CPP_BINDINGS_ARRAY_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_ARRAY_H_
+
+#include <string.h>
+
+#include <algorithm>
+#include <string>
+#include <vector>
+
+#include "mojo/public/cpp/bindings/lib/array_internal.h"
+#include "mojo/public/cpp/bindings/lib/template_util.h"
+#include "mojo/public/cpp/bindings/type_converter.h"
+
+namespace mojo {
+
+// Provides read-only access to array data.
+template <typename T>
+class Array {
+ MOJO_MOVE_ONLY_TYPE_FOR_CPP_03(Array, RValue)
+ public:
+ typedef internal::ArrayTraits<T, internal::IsMoveOnlyType<T>::value>
+ Traits;
+ typedef typename Traits::ConstRefType ConstRefType;
+ typedef typename Traits::RefType RefType;
+ typedef typename Traits::StorageType StorageType;
+ typedef typename Traits::ForwardType ForwardType;
+
+ typedef internal::Array_Data<typename internal::WrapperTraits<T>::DataType>
+ Data_;
+
+ Array() : is_null_(true) {}
+ explicit Array(size_t size) : vec_(size), is_null_(false) {
+ Traits::Initialize(&vec_);
+ }
+ ~Array() { Traits::Finalize(&vec_); }
+
+ Array(RValue other) : is_null_(true) { Take(other.object); }
+ Array& operator=(RValue other) {
+ Take(other.object);
+ return *this;
+ }
+
+ static Array New(size_t size) {
+ return Array(size).Pass();
+ }
+
+ template <typename U>
+ static Array From(const U& other) {
+ return TypeConverter<Array, U>::ConvertFrom(other);
+ }
+
+ template <typename U>
+ U To() const {
+ return TypeConverter<Array, U>::ConvertTo(*this);
+ }
+
+ void reset() {
+ if (!vec_.empty()) {
+ Traits::Finalize(&vec_);
+ vec_.clear();
+ }
+ is_null_ = true;
+ }
+
+ bool is_null() const { return is_null_; }
+
+ size_t size() const { return vec_.size(); }
+
+ ConstRefType at(size_t offset) const { return Traits::at(&vec_, offset); }
+ ConstRefType operator[](size_t offset) const { return at(offset); }
+
+ RefType at(size_t offset) { return Traits::at(&vec_, offset); }
+ RefType operator[](size_t offset) { return at(offset); }
+
+ void push_back(ForwardType value) {
+ is_null_ = false;
+ Traits::PushBack(&vec_, value);
+ }
+
+ void resize(size_t size) {
+ is_null_ = false;
+ Traits::Resize(&vec_, size);
+ }
+
+ const std::vector<StorageType>& storage() const {
+ return vec_;
+ }
+ operator const std::vector<StorageType>&() const {
+ return vec_;
+ }
+
+ void Swap(Array* other) {
+ std::swap(is_null_, other->is_null_);
+ vec_.swap(other->vec_);
+ }
+ void Swap(std::vector<StorageType>* other) {
+ is_null_ = false;
+ vec_.swap(*other);
+ }
+
+ private:
+ typedef std::vector<StorageType> Array::*Testable;
+
+ public:
+ operator Testable() const { return is_null_ ? 0 : &Array::vec_; }
+
+ private:
+ void Take(Array* other) {
+ reset();
+ Swap(other);
+ }
+
+ std::vector<StorageType> vec_;
+ bool is_null_;
+};
+
+template <typename T, typename E>
+class TypeConverter<Array<T>, std::vector<E> > {
+ public:
+ static Array<T> ConvertFrom(const std::vector<E>& input) {
+ Array<T> result(input.size());
+ for (size_t i = 0; i < input.size(); ++i)
+ result[i] = TypeConverter<T, E>::ConvertFrom(input[i]);
+ return result.Pass();
+ }
+ static std::vector<E> ConvertTo(const Array<T>& input) {
+ std::vector<E> result;
+ if (!input.is_null()) {
+ result.resize(input.size());
+ for (size_t i = 0; i < input.size(); ++i)
+ result[i] = TypeConverter<T, E>::ConvertTo(input[i]);
+ }
+ return result;
+ }
+};
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_ARRAY_H_
diff --git a/chromium/mojo/public/cpp/bindings/callback.h b/chromium/mojo/public/cpp/bindings/callback.h
new file mode 100644
index 00000000000..d8ff4718232
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/callback.h
@@ -0,0 +1,462 @@
+// This file was GENERATED by command:
+// pump.py callback.h.pump
+// DO NOT EDIT BY HAND!!!
+
+
+
+// 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.
+
+#ifndef MOJO_PUBLIC_CPP_BINDINGS_CALLBACK_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_CALLBACK_H_
+
+#include "mojo/public/cpp/bindings/lib/callback_internal.h"
+#include "mojo/public/cpp/bindings/lib/shared_ptr.h"
+#include "mojo/public/cpp/bindings/lib/template_util.h"
+
+namespace mojo {
+
+template <typename Sig>
+class Callback;
+
+template <>
+class Callback<void()> {
+ public:
+ struct Runnable {
+ virtual ~Runnable() {}
+ virtual void Run() const = 0;
+ };
+
+ Callback() {}
+
+ // The Callback assumes ownership of |runnable|.
+ explicit Callback(Runnable* runnable) : sink_(runnable) {}
+
+ // Any class that is copy-constructable and has a compatible Run method may
+ // be adapted to a Callback using this constructor.
+ template <typename Sink>
+ Callback(const Sink& sink) : sink_(new Adapter<Sink>(sink)) {}
+
+ void Run() const {
+ if (sink_.get())
+ sink_->Run();
+ }
+
+ private:
+ template <typename Sink>
+ struct Adapter : public Runnable {
+ explicit Adapter(const Sink& sink) : sink(sink) {}
+ virtual void Run() const MOJO_OVERRIDE {
+ sink.Run();
+ }
+ Sink sink;
+ };
+
+ internal::SharedPtr<Runnable> sink_;
+};
+
+template <typename A1>
+class Callback<void(A1)> {
+ public:
+ struct Runnable {
+ virtual ~Runnable() {}
+ virtual void Run(
+ typename internal::Callback_ParamTraits<A1>::ForwardType a1) const = 0;
+ };
+
+ Callback() {}
+
+ // The Callback assumes ownership of |runnable|.
+ explicit Callback(Runnable* runnable) : sink_(runnable) {}
+
+ // Any class that is copy-constructable and has a compatible Run method may
+ // be adapted to a Callback using this constructor.
+ template <typename Sink>
+ Callback(const Sink& sink) : sink_(new Adapter<Sink>(sink)) {}
+
+ void Run(
+ typename internal::Callback_ParamTraits<A1>::ForwardType a1) const {
+ if (sink_.get())
+ sink_->Run(
+ internal::Forward(a1));
+ }
+
+ private:
+ template <typename Sink>
+ struct Adapter : public Runnable {
+ explicit Adapter(const Sink& sink) : sink(sink) {}
+ virtual void Run(
+ typename internal::Callback_ParamTraits<A1>::ForwardType a1) const
+ MOJO_OVERRIDE {
+ sink.Run(
+ internal::Forward(a1));
+ }
+ Sink sink;
+ };
+
+ internal::SharedPtr<Runnable> sink_;
+};
+
+template <typename A1, typename A2>
+class Callback<void(A1, A2)> {
+ public:
+ struct Runnable {
+ virtual ~Runnable() {}
+ virtual void Run(
+ typename internal::Callback_ParamTraits<A1>::ForwardType a1,
+ typename internal::Callback_ParamTraits<A2>::ForwardType a2) const = 0;
+ };
+
+ Callback() {}
+
+ // The Callback assumes ownership of |runnable|.
+ explicit Callback(Runnable* runnable) : sink_(runnable) {}
+
+ // Any class that is copy-constructable and has a compatible Run method may
+ // be adapted to a Callback using this constructor.
+ template <typename Sink>
+ Callback(const Sink& sink) : sink_(new Adapter<Sink>(sink)) {}
+
+ void Run(
+ typename internal::Callback_ParamTraits<A1>::ForwardType a1,
+ typename internal::Callback_ParamTraits<A2>::ForwardType a2) const {
+ if (sink_.get())
+ sink_->Run(
+ internal::Forward(a1),
+ internal::Forward(a2));
+ }
+
+ private:
+ template <typename Sink>
+ struct Adapter : public Runnable {
+ explicit Adapter(const Sink& sink) : sink(sink) {}
+ virtual void Run(
+ typename internal::Callback_ParamTraits<A1>::ForwardType a1,
+ typename internal::Callback_ParamTraits<A2>::ForwardType a2) const
+ MOJO_OVERRIDE {
+ sink.Run(
+ internal::Forward(a1),
+ internal::Forward(a2));
+ }
+ Sink sink;
+ };
+
+ internal::SharedPtr<Runnable> sink_;
+};
+
+template <typename A1, typename A2, typename A3>
+class Callback<void(A1, A2, A3)> {
+ public:
+ struct Runnable {
+ virtual ~Runnable() {}
+ virtual void Run(
+ typename internal::Callback_ParamTraits<A1>::ForwardType a1,
+ typename internal::Callback_ParamTraits<A2>::ForwardType a2,
+ typename internal::Callback_ParamTraits<A3>::ForwardType a3) const = 0;
+ };
+
+ Callback() {}
+
+ // The Callback assumes ownership of |runnable|.
+ explicit Callback(Runnable* runnable) : sink_(runnable) {}
+
+ // Any class that is copy-constructable and has a compatible Run method may
+ // be adapted to a Callback using this constructor.
+ template <typename Sink>
+ Callback(const Sink& sink) : sink_(new Adapter<Sink>(sink)) {}
+
+ void Run(
+ typename internal::Callback_ParamTraits<A1>::ForwardType a1,
+ typename internal::Callback_ParamTraits<A2>::ForwardType a2,
+ typename internal::Callback_ParamTraits<A3>::ForwardType a3) const {
+ if (sink_.get())
+ sink_->Run(
+ internal::Forward(a1),
+ internal::Forward(a2),
+ internal::Forward(a3));
+ }
+
+ private:
+ template <typename Sink>
+ struct Adapter : public Runnable {
+ explicit Adapter(const Sink& sink) : sink(sink) {}
+ virtual void Run(
+ typename internal::Callback_ParamTraits<A1>::ForwardType a1,
+ typename internal::Callback_ParamTraits<A2>::ForwardType a2,
+ typename internal::Callback_ParamTraits<A3>::ForwardType a3) const
+ MOJO_OVERRIDE {
+ sink.Run(
+ internal::Forward(a1),
+ internal::Forward(a2),
+ internal::Forward(a3));
+ }
+ Sink sink;
+ };
+
+ internal::SharedPtr<Runnable> sink_;
+};
+
+template <typename A1, typename A2, typename A3, typename A4>
+class Callback<void(A1, A2, A3, A4)> {
+ public:
+ struct Runnable {
+ virtual ~Runnable() {}
+ virtual void Run(
+ typename internal::Callback_ParamTraits<A1>::ForwardType a1,
+ typename internal::Callback_ParamTraits<A2>::ForwardType a2,
+ typename internal::Callback_ParamTraits<A3>::ForwardType a3,
+ typename internal::Callback_ParamTraits<A4>::ForwardType a4) const = 0;
+ };
+
+ Callback() {}
+
+ // The Callback assumes ownership of |runnable|.
+ explicit Callback(Runnable* runnable) : sink_(runnable) {}
+
+ // Any class that is copy-constructable and has a compatible Run method may
+ // be adapted to a Callback using this constructor.
+ template <typename Sink>
+ Callback(const Sink& sink) : sink_(new Adapter<Sink>(sink)) {}
+
+ void Run(
+ typename internal::Callback_ParamTraits<A1>::ForwardType a1,
+ typename internal::Callback_ParamTraits<A2>::ForwardType a2,
+ typename internal::Callback_ParamTraits<A3>::ForwardType a3,
+ typename internal::Callback_ParamTraits<A4>::ForwardType a4) const {
+ if (sink_.get())
+ sink_->Run(
+ internal::Forward(a1),
+ internal::Forward(a2),
+ internal::Forward(a3),
+ internal::Forward(a4));
+ }
+
+ private:
+ template <typename Sink>
+ struct Adapter : public Runnable {
+ explicit Adapter(const Sink& sink) : sink(sink) {}
+ virtual void Run(
+ typename internal::Callback_ParamTraits<A1>::ForwardType a1,
+ typename internal::Callback_ParamTraits<A2>::ForwardType a2,
+ typename internal::Callback_ParamTraits<A3>::ForwardType a3,
+ typename internal::Callback_ParamTraits<A4>::ForwardType a4) const
+ MOJO_OVERRIDE {
+ sink.Run(
+ internal::Forward(a1),
+ internal::Forward(a2),
+ internal::Forward(a3),
+ internal::Forward(a4));
+ }
+ Sink sink;
+ };
+
+ internal::SharedPtr<Runnable> sink_;
+};
+
+template <typename A1, typename A2, typename A3, typename A4, typename A5>
+class Callback<void(A1, A2, A3, A4, A5)> {
+ public:
+ struct Runnable {
+ virtual ~Runnable() {}
+ virtual void Run(
+ typename internal::Callback_ParamTraits<A1>::ForwardType a1,
+ typename internal::Callback_ParamTraits<A2>::ForwardType a2,
+ typename internal::Callback_ParamTraits<A3>::ForwardType a3,
+ typename internal::Callback_ParamTraits<A4>::ForwardType a4,
+ typename internal::Callback_ParamTraits<A5>::ForwardType a5) const = 0;
+ };
+
+ Callback() {}
+
+ // The Callback assumes ownership of |runnable|.
+ explicit Callback(Runnable* runnable) : sink_(runnable) {}
+
+ // Any class that is copy-constructable and has a compatible Run method may
+ // be adapted to a Callback using this constructor.
+ template <typename Sink>
+ Callback(const Sink& sink) : sink_(new Adapter<Sink>(sink)) {}
+
+ void Run(
+ typename internal::Callback_ParamTraits<A1>::ForwardType a1,
+ typename internal::Callback_ParamTraits<A2>::ForwardType a2,
+ typename internal::Callback_ParamTraits<A3>::ForwardType a3,
+ typename internal::Callback_ParamTraits<A4>::ForwardType a4,
+ typename internal::Callback_ParamTraits<A5>::ForwardType a5) const {
+ if (sink_.get())
+ sink_->Run(
+ internal::Forward(a1),
+ internal::Forward(a2),
+ internal::Forward(a3),
+ internal::Forward(a4),
+ internal::Forward(a5));
+ }
+
+ private:
+ template <typename Sink>
+ struct Adapter : public Runnable {
+ explicit Adapter(const Sink& sink) : sink(sink) {}
+ virtual void Run(
+ typename internal::Callback_ParamTraits<A1>::ForwardType a1,
+ typename internal::Callback_ParamTraits<A2>::ForwardType a2,
+ typename internal::Callback_ParamTraits<A3>::ForwardType a3,
+ typename internal::Callback_ParamTraits<A4>::ForwardType a4,
+ typename internal::Callback_ParamTraits<A5>::ForwardType a5) const
+ MOJO_OVERRIDE {
+ sink.Run(
+ internal::Forward(a1),
+ internal::Forward(a2),
+ internal::Forward(a3),
+ internal::Forward(a4),
+ internal::Forward(a5));
+ }
+ Sink sink;
+ };
+
+ internal::SharedPtr<Runnable> sink_;
+};
+
+template <typename A1, typename A2, typename A3, typename A4, typename A5,
+ typename A6>
+class Callback<void(A1, A2, A3, A4, A5, A6)> {
+ public:
+ struct Runnable {
+ virtual ~Runnable() {}
+ virtual void Run(
+ typename internal::Callback_ParamTraits<A1>::ForwardType a1,
+ typename internal::Callback_ParamTraits<A2>::ForwardType a2,
+ typename internal::Callback_ParamTraits<A3>::ForwardType a3,
+ typename internal::Callback_ParamTraits<A4>::ForwardType a4,
+ typename internal::Callback_ParamTraits<A5>::ForwardType a5,
+ typename internal::Callback_ParamTraits<A6>::ForwardType a6) const = 0;
+ };
+
+ Callback() {}
+
+ // The Callback assumes ownership of |runnable|.
+ explicit Callback(Runnable* runnable) : sink_(runnable) {}
+
+ // Any class that is copy-constructable and has a compatible Run method may
+ // be adapted to a Callback using this constructor.
+ template <typename Sink>
+ Callback(const Sink& sink) : sink_(new Adapter<Sink>(sink)) {}
+
+ void Run(
+ typename internal::Callback_ParamTraits<A1>::ForwardType a1,
+ typename internal::Callback_ParamTraits<A2>::ForwardType a2,
+ typename internal::Callback_ParamTraits<A3>::ForwardType a3,
+ typename internal::Callback_ParamTraits<A4>::ForwardType a4,
+ typename internal::Callback_ParamTraits<A5>::ForwardType a5,
+ typename internal::Callback_ParamTraits<A6>::ForwardType a6) const {
+ if (sink_.get())
+ sink_->Run(
+ internal::Forward(a1),
+ internal::Forward(a2),
+ internal::Forward(a3),
+ internal::Forward(a4),
+ internal::Forward(a5),
+ internal::Forward(a6));
+ }
+
+ private:
+ template <typename Sink>
+ struct Adapter : public Runnable {
+ explicit Adapter(const Sink& sink) : sink(sink) {}
+ virtual void Run(
+ typename internal::Callback_ParamTraits<A1>::ForwardType a1,
+ typename internal::Callback_ParamTraits<A2>::ForwardType a2,
+ typename internal::Callback_ParamTraits<A3>::ForwardType a3,
+ typename internal::Callback_ParamTraits<A4>::ForwardType a4,
+ typename internal::Callback_ParamTraits<A5>::ForwardType a5,
+ typename internal::Callback_ParamTraits<A6>::ForwardType a6) const
+ MOJO_OVERRIDE {
+ sink.Run(
+ internal::Forward(a1),
+ internal::Forward(a2),
+ internal::Forward(a3),
+ internal::Forward(a4),
+ internal::Forward(a5),
+ internal::Forward(a6));
+ }
+ Sink sink;
+ };
+
+ internal::SharedPtr<Runnable> sink_;
+};
+
+template <typename A1, typename A2, typename A3, typename A4, typename A5,
+ typename A6, typename A7>
+class Callback<void(A1, A2, A3, A4, A5, A6, A7)> {
+ public:
+ struct Runnable {
+ virtual ~Runnable() {}
+ virtual void Run(
+ typename internal::Callback_ParamTraits<A1>::ForwardType a1,
+ typename internal::Callback_ParamTraits<A2>::ForwardType a2,
+ typename internal::Callback_ParamTraits<A3>::ForwardType a3,
+ typename internal::Callback_ParamTraits<A4>::ForwardType a4,
+ typename internal::Callback_ParamTraits<A5>::ForwardType a5,
+ typename internal::Callback_ParamTraits<A6>::ForwardType a6,
+ typename internal::Callback_ParamTraits<A7>::ForwardType a7) const = 0;
+ };
+
+ Callback() {}
+
+ // The Callback assumes ownership of |runnable|.
+ explicit Callback(Runnable* runnable) : sink_(runnable) {}
+
+ // Any class that is copy-constructable and has a compatible Run method may
+ // be adapted to a Callback using this constructor.
+ template <typename Sink>
+ Callback(const Sink& sink) : sink_(new Adapter<Sink>(sink)) {}
+
+ void Run(
+ typename internal::Callback_ParamTraits<A1>::ForwardType a1,
+ typename internal::Callback_ParamTraits<A2>::ForwardType a2,
+ typename internal::Callback_ParamTraits<A3>::ForwardType a3,
+ typename internal::Callback_ParamTraits<A4>::ForwardType a4,
+ typename internal::Callback_ParamTraits<A5>::ForwardType a5,
+ typename internal::Callback_ParamTraits<A6>::ForwardType a6,
+ typename internal::Callback_ParamTraits<A7>::ForwardType a7) const {
+ if (sink_.get())
+ sink_->Run(
+ internal::Forward(a1),
+ internal::Forward(a2),
+ internal::Forward(a3),
+ internal::Forward(a4),
+ internal::Forward(a5),
+ internal::Forward(a6),
+ internal::Forward(a7));
+ }
+
+ private:
+ template <typename Sink>
+ struct Adapter : public Runnable {
+ explicit Adapter(const Sink& sink) : sink(sink) {}
+ virtual void Run(
+ typename internal::Callback_ParamTraits<A1>::ForwardType a1,
+ typename internal::Callback_ParamTraits<A2>::ForwardType a2,
+ typename internal::Callback_ParamTraits<A3>::ForwardType a3,
+ typename internal::Callback_ParamTraits<A4>::ForwardType a4,
+ typename internal::Callback_ParamTraits<A5>::ForwardType a5,
+ typename internal::Callback_ParamTraits<A6>::ForwardType a6,
+ typename internal::Callback_ParamTraits<A7>::ForwardType a7) const
+ MOJO_OVERRIDE {
+ sink.Run(
+ internal::Forward(a1),
+ internal::Forward(a2),
+ internal::Forward(a3),
+ internal::Forward(a4),
+ internal::Forward(a5),
+ internal::Forward(a6),
+ internal::Forward(a7));
+ }
+ Sink sink;
+ };
+
+ internal::SharedPtr<Runnable> sink_;
+};
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_CALLBACK_H_
diff --git a/chromium/mojo/public/cpp/bindings/callback.h.pump b/chromium/mojo/public/cpp/bindings/callback.h.pump
new file mode 100644
index 00000000000..a0f23d5f77e
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/callback.h.pump
@@ -0,0 +1,80 @@
+$$ This is a pump file for generating file templates. Pump is a python
+$$ script that is part of the Google Test suite of utilities. Description
+$$ can be found here:
+$$
+$$ http://code.google.com/p/googletest/wiki/PumpManual
+$$
+
+$var MAX_ARITY = 7
+
+// 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.
+
+#ifndef MOJO_PUBLIC_CPP_BINDINGS_CALLBACK_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_CALLBACK_H_
+
+#include "mojo/public/cpp/bindings/lib/callback_internal.h"
+#include "mojo/public/cpp/bindings/lib/shared_ptr.h"
+#include "mojo/public/cpp/bindings/lib/template_util.h"
+
+namespace mojo {
+
+template <typename Sig>
+class Callback;
+
+$range ARITY 0..MAX_ARITY
+$for ARITY [[
+$range ARG 1..ARITY
+
+template <$for ARG , [[typename A$(ARG)]]>
+class Callback<void($for ARG , [[A$(ARG)]])> {
+ public:
+ struct Runnable {
+ virtual ~Runnable() {}
+ virtual void Run(
+ $for ARG ,
+ [[typename internal::Callback_ParamTraits<A$(ARG)>::ForwardType a$(ARG)]]) const = 0;
+ };
+
+ Callback() {}
+
+ // The Callback assumes ownership of |runnable|.
+ explicit Callback(Runnable* runnable) : sink_(runnable) {}
+
+ // Any class that is copy-constructable and has a compatible Run method may
+ // be adapted to a Callback using this constructor.
+ template <typename Sink>
+ Callback(const Sink& sink) : sink_(new Adapter<Sink>(sink)) {}
+
+ void Run(
+ $for ARG ,
+ [[typename internal::Callback_ParamTraits<A$(ARG)>::ForwardType a$(ARG)]]) const {
+ if (sink_.get())
+ sink_->Run(
+ $for ARG ,
+ [[internal::Forward(a$(ARG))]]);
+ }
+
+ private:
+ template <typename Sink>
+ struct Adapter : public Runnable {
+ explicit Adapter(const Sink& sink) : sink(sink) {}
+ virtual void Run(
+ $for ARG ,
+ [[typename internal::Callback_ParamTraits<A$(ARG)>::ForwardType a$(ARG)]]) const MOJO_OVERRIDE {
+ sink.Run(
+ $for ARG ,
+ [[internal::Forward(a$(ARG))]]);
+ }
+ Sink sink;
+ };
+
+ internal::SharedPtr<Runnable> sink_;
+};
+
+]] $$ for ARITY
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_CALLBACK_H_
diff --git a/chromium/mojo/public/cpp/bindings/error_handler.h b/chromium/mojo/public/cpp/bindings/error_handler.h
new file mode 100644
index 00000000000..8ce1af27264
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/error_handler.h
@@ -0,0 +1,19 @@
+// 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.
+
+#ifndef MOJO_PUBLIC_CPP_BINDINGS_ERROR_HANDLER_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_ERROR_HANDLER_H_
+
+namespace mojo {
+
+// This interface is used to report connection errors.
+class ErrorHandler {
+ public:
+ virtual ~ErrorHandler() {}
+ virtual void OnConnectionError() = 0;
+};
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_ERROR_HANDLER_H_
diff --git a/chromium/mojo/public/cpp/bindings/interface_impl.h b/chromium/mojo/public/cpp/bindings/interface_impl.h
new file mode 100644
index 00000000000..8ba5e7ffa4a
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/interface_impl.h
@@ -0,0 +1,109 @@
+// 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.
+
+#ifndef MOJO_PUBLIC_CPP_BINDINGS_INTERFACE_IMPL_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_INTERFACE_IMPL_H_
+
+#include "mojo/public/cpp/bindings/interface_request.h"
+#include "mojo/public/cpp/bindings/lib/interface_impl_internal.h"
+#include "mojo/public/cpp/environment/environment.h"
+#include "mojo/public/cpp/system/macros.h"
+
+namespace mojo {
+
+// InterfaceImpl<..> is designed to be the base class of an interface
+// implementation. It may be bound to a pipe or a proxy, see BindToPipe and
+// BindToProxy.
+template <typename Interface>
+class InterfaceImpl : public internal::InterfaceImplBase<Interface> {
+ public:
+ typedef typename Interface::Client Client;
+
+ InterfaceImpl() : internal_state_(this) {}
+ virtual ~InterfaceImpl() {}
+
+ // Returns a proxy to the client interface. This is null upon construction,
+ // and becomes non-null after OnClientConnected. NOTE: It remains non-null
+ // until this instance is deleted.
+ Client* client() { return internal_state_.client(); }
+
+ // Called when the client has connected to this instance.
+ virtual void OnConnectionEstablished() {}
+
+ // Called when the client is no longer connected to this instance. NOTE: The
+ // client() method continues to return a non-null pointer after this method
+ // is called. After this method is called, any method calls made on client()
+ // will be silently ignored.
+ virtual void OnConnectionError() {}
+
+ // DO NOT USE. Exposed only for internal use and for testing.
+ internal::InterfaceImplState<Interface>* internal_state() {
+ return &internal_state_;
+ }
+
+ private:
+ internal::InterfaceImplState<Interface> internal_state_;
+ MOJO_DISALLOW_COPY_AND_ASSIGN(InterfaceImpl);
+};
+
+// Takes an instance of an InterfaceImpl<..> subclass and binds it to the given
+// MessagePipe. The instance is returned for convenience in member initializer
+// lists, etc. If the pipe is closed, the instance's OnConnectionError method
+// will be called.
+//
+// The instance is also bound to the current thread. Its methods will only be
+// called on the current thread, and if the current thread exits, then it will
+// also be deleted, and along with it, its end point of the pipe will be closed.
+//
+// Before returning, the instance's OnConnectionEstablished method is called.
+template <typename Impl>
+Impl* BindToPipe(
+ Impl* instance,
+ ScopedMessagePipeHandle handle,
+ const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) {
+ instance->internal_state()->Bind(handle.Pass(), waiter);
+ return instance;
+}
+
+// Takes an instance of an InterfaceImpl<..> subclass and binds it to the given
+// InterfacePtr<..>. The instance is returned for convenience in member
+// initializer lists, etc. If the pipe is closed, the instance's
+// OnConnectionError method will be called.
+//
+// The instance is also bound to the current thread. Its methods will only be
+// called on the current thread, and if the current thread exits, then it will
+// also be deleted, and along with it, its end point of the pipe will be closed.
+//
+// Before returning, the instance's OnConnectionEstablished method is called.
+template <typename Impl, typename Interface>
+Impl* BindToProxy(
+ Impl* instance,
+ InterfacePtr<Interface>* ptr,
+ const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) {
+ instance->internal_state()->BindProxy(ptr, waiter);
+ return instance;
+}
+
+// Takes an instance of an InterfaceImpl<..> subclass and binds it to the given
+// InterfaceRequest<..>. The instance is returned for convenience in member
+// initializer lists, etc. If the pipe is closed, the instance's
+// OnConnectionError method will be called.
+//
+// The instance is also bound to the current thread. Its methods will only be
+// called on the current thread, and if the current thread exits, then it will
+// also be deleted, and along with it, its end point of the pipe will be closed.
+//
+// Before returning, the instance will receive a SetClient call, providing it
+// with a proxy to the client on the other end of the pipe.
+template <typename Impl, typename Interface>
+Impl* BindToRequest(
+ Impl* instance,
+ InterfaceRequest<Interface>* request,
+ const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) {
+ return BindToPipe(instance, request->PassMessagePipe(), waiter);
+}
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_INTERFACE_IMPL_H_
diff --git a/chromium/mojo/public/cpp/bindings/interface_ptr.h b/chromium/mojo/public/cpp/bindings/interface_ptr.h
new file mode 100644
index 00000000000..726896d9cce
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/interface_ptr.h
@@ -0,0 +1,124 @@
+// 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.
+
+#ifndef MOJO_PUBLIC_CPP_BINDINGS_INTERFACE_PTR_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_INTERFACE_PTR_H_
+
+#include <assert.h>
+
+#include <algorithm>
+
+#include "mojo/public/cpp/bindings/error_handler.h"
+#include "mojo/public/cpp/bindings/lib/interface_ptr_internal.h"
+#include "mojo/public/cpp/environment/environment.h"
+#include "mojo/public/cpp/system/macros.h"
+
+namespace mojo {
+class ErrorHandler;
+
+// InterfacePtr represents a proxy to a remote instance of an interface.
+template <typename Interface>
+class InterfacePtr {
+ MOJO_MOVE_ONLY_TYPE_FOR_CPP_03(InterfacePtr, RValue)
+ public:
+ InterfacePtr() {}
+
+ InterfacePtr(RValue other) {
+ internal_state_.Swap(&other.object->internal_state_);
+ }
+ InterfacePtr& operator=(RValue other) {
+ reset();
+ internal_state_.Swap(&other.object->internal_state_);
+ return *this;
+ }
+
+ ~InterfacePtr() {}
+
+ Interface* get() const {
+ return internal_state_.instance();
+ }
+ Interface* operator->() const { return get(); }
+ Interface& operator*() const { return *get(); }
+
+ void reset() {
+ State doomed;
+ internal_state_.Swap(&doomed);
+ }
+
+ // This method configures the InterfacePtr<..> to be a proxy to a remote
+ // object on the other end of the given pipe.
+ //
+ // The proxy is bound to the current thread, which means its methods may
+ // only be called on the current thread.
+ //
+ // To move a bound InterfacePtr<..> to another thread, call
+ // ResetAndReturnMessagePipe. Then create a new InterfacePtr<..> on another
+ // thread, and bind the new InterfacePtr<..> to the message pipe on that
+ // thread.
+ void Bind(
+ ScopedMessagePipeHandle handle,
+ const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) {
+ reset();
+ internal_state_.ConfigureProxy(handle.Pass(), waiter);
+ }
+
+ // The client interface may only be set after this InterfacePtr<..> is bound.
+ void set_client(typename Interface::Client* client) {
+ internal_state_.set_client(client);
+ }
+
+ // This method may be called to query if the underlying pipe has encountered
+ // an error. If true, this means method calls made on this interface will be
+ // dropped (and may have already been dropped) on the floor.
+ bool encountered_error() const {
+ assert(internal_state_.router());
+ return internal_state_.router()->encountered_error();
+ }
+
+ // This method may be called to register an ErrorHandler to observe a
+ // connection error on the underlying pipe. The callback runs asynchronously
+ // from the current message loop.
+ void set_error_handler(ErrorHandler* error_handler) {
+ assert(internal_state_.router());
+ internal_state_.router()->set_error_handler(error_handler);
+ }
+
+ // Returns the underlying message pipe handle (if any) and resets the
+ // InterfacePtr<..> to its uninitialized state. This method is helpful if you
+ // need to move a proxy to another thread. See related notes for Bind.
+ ScopedMessagePipeHandle PassMessagePipe() {
+ State state;
+ internal_state_.Swap(&state);
+ return state.router() ?
+ state.router()->PassMessagePipe() : ScopedMessagePipeHandle();
+ }
+
+ // DO NOT USE. Exposed only for internal use and for testing.
+ internal::InterfacePtrState<Interface>* internal_state() {
+ return &internal_state_;
+ }
+
+ private:
+ typedef internal::InterfacePtrState<Interface> State;
+ State internal_state_;
+};
+
+// Takes a handle to the proxy end-point of a pipe. On the other end is
+// presumed to be an interface implementation of type |Interface|. Returns a
+// generated proxy to that interface, which may be used on the current thread.
+// It is valid to call set_client on the returned InterfacePtr<..> to set an
+// instance of Interface::Client.
+template <typename Interface>
+InterfacePtr<Interface> MakeProxy(
+ ScopedMessagePipeHandle handle,
+ const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) {
+ InterfacePtr<Interface> ptr;
+ if (handle.is_valid())
+ ptr.Bind(handle.Pass(), waiter);
+ return ptr.Pass();
+}
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_INTERFACE_PTR_H_
diff --git a/chromium/mojo/public/cpp/bindings/interface_request.h b/chromium/mojo/public/cpp/bindings/interface_request.h
new file mode 100644
index 00000000000..6b7d3033c9d
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/interface_request.h
@@ -0,0 +1,76 @@
+// 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.
+
+#ifndef MOJO_PUBLIC_CPP_BINDINGS_INTERFACE_REQUEST_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_INTERFACE_REQUEST_H_
+
+#include "mojo/public/cpp/bindings/interface_ptr.h"
+
+namespace mojo {
+
+// Used in methods that return instances of remote objects.
+template <typename Interface>
+class InterfaceRequest {
+ MOJO_MOVE_ONLY_TYPE_FOR_CPP_03(InterfaceRequest, RValue)
+ public:
+ InterfaceRequest() {}
+
+ InterfaceRequest(RValue other) {
+ handle_ = other.object->handle_.Pass();
+ }
+ InterfaceRequest& operator=(RValue other) {
+ handle_ = other.object->handle_.Pass();
+ return *this;
+ }
+
+ // Returns true if the request has yet to be completed.
+ bool is_pending() const { return handle_.is_valid(); }
+
+ void Bind(ScopedMessagePipeHandle handle) {
+ handle_ = handle.Pass();
+ }
+
+ ScopedMessagePipeHandle PassMessagePipe() {
+ return handle_.Pass();
+ }
+
+ private:
+ ScopedMessagePipeHandle handle_;
+};
+
+template <typename Interface>
+InterfaceRequest<Interface> MakeRequest(ScopedMessagePipeHandle handle) {
+ InterfaceRequest<Interface> request;
+ request.Bind(handle.Pass());
+ return request.Pass();
+}
+
+// Used to construct a request that synchronously binds an InterfacePtr<..>,
+// making it immediately usable upon return. The resulting request object may
+// then be later bound to an InterfaceImpl<..> via BindToRequest.
+//
+// Given the following interface:
+//
+// interface Foo {
+// CreateBar(Bar& bar);
+// }
+//
+// The caller of CreateBar would have code similar to the following:
+//
+// InterfacePtr<Foo> foo = ...;
+// InterfacePtr<Bar> bar;
+// foo->CreateBar(Get(&bar));
+//
+// Upon return from CreateBar, |bar| is ready to have methods called on it.
+//
+template <typename Interface>
+InterfaceRequest<Interface> Get(InterfacePtr<Interface>* ptr) {
+ MessagePipe pipe;
+ ptr->Bind(pipe.handle0.Pass());
+ return MakeRequest<Interface>(pipe.handle1.Pass());
+}
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_INTERFACE_REQUEST_H_
diff --git a/chromium/mojo/public/cpp/bindings/lib/DEPS b/chromium/mojo/public/cpp/bindings/lib/DEPS
new file mode 100644
index 00000000000..b809b58d337
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/DEPS
@@ -0,0 +1,5 @@
+include_rules = [
+ "+mojo/public/cpp/bindings",
+ "+mojo/public/cpp/environment",
+ "+mojo/public/cpp/system",
+]
diff --git a/chromium/mojo/public/cpp/bindings/lib/TODO b/chromium/mojo/public/cpp/bindings/lib/TODO
new file mode 100644
index 00000000000..21bcb6fe7a2
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/TODO
@@ -0,0 +1,6 @@
+TODOs:
+ - Ensure validation checks are solid
+ - Add tests of validation logic
+ - Optimize Buffer classes?
+ - Add compile-time asserts to verify object packing and padding.
+ - Investigate making arrays of objects not be arrays of pointers.
diff --git a/chromium/mojo/public/cpp/bindings/lib/array_internal.cc b/chromium/mojo/public/cpp/bindings/lib/array_internal.cc
new file mode 100644
index 00000000000..3f7f1ce0b16
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/array_internal.cc
@@ -0,0 +1,70 @@
+// Copyright 2013 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/public/cpp/bindings/lib/array_internal.h"
+
+namespace mojo {
+namespace internal {
+
+ArrayDataTraits<bool>::BitRef::~BitRef() {
+}
+
+ArrayDataTraits<bool>::BitRef::BitRef(uint8_t* storage, uint8_t mask)
+ : storage_(storage),
+ mask_(mask) {
+}
+
+ArrayDataTraits<bool>::BitRef&
+ArrayDataTraits<bool>::BitRef::operator=(bool value) {
+ if (value) {
+ *storage_ |= mask_;
+ } else {
+ *storage_ &= ~mask_;
+ }
+ return *this;
+}
+
+ArrayDataTraits<bool>::BitRef&
+ArrayDataTraits<bool>::BitRef::operator=(const BitRef& value) {
+ return (*this) = static_cast<bool>(value);
+}
+
+ArrayDataTraits<bool>::BitRef::operator bool() const {
+ return (*storage_ & mask_) != 0;
+}
+
+// static
+void ArraySerializationHelper<Handle, true>::EncodePointersAndHandles(
+ const ArrayHeader* header,
+ ElementType* elements,
+ std::vector<Handle>* handles) {
+ for (uint32_t i = 0; i < header->num_elements; ++i)
+ EncodeHandle(&elements[i], handles);
+}
+
+// static
+void ArraySerializationHelper<Handle, true>::DecodePointersAndHandles(
+ const ArrayHeader* header,
+ ElementType* elements,
+ std::vector<Handle>* handles) {
+ for (uint32_t i = 0; i < header->num_elements; ++i)
+ DecodeHandle(&elements[i], handles);
+}
+
+// static
+bool ArraySerializationHelper<Handle, true>::ValidateElements(
+ const ArrayHeader* header,
+ const ElementType* elements,
+ BoundsChecker* bounds_checker) {
+ for (uint32_t i = 0; i < header->num_elements; ++i) {
+ if (!bounds_checker->ClaimHandle(elements[i])) {
+ ReportValidationError(VALIDATION_ERROR_ILLEGAL_HANDLE);
+ return false;
+ }
+ }
+ return true;
+}
+
+} // namespace internal
+} // namespace mojo
diff --git a/chromium/mojo/public/cpp/bindings/lib/array_internal.h b/chromium/mojo/public/cpp/bindings/lib/array_internal.h
new file mode 100644
index 00000000000..8ea00991251
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/array_internal.h
@@ -0,0 +1,384 @@
+// Copyright 2013 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.
+
+#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_INTERNAL_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_INTERNAL_H_
+
+#include <new>
+#include <vector>
+
+#include "mojo/public/cpp/bindings/lib/bindings_internal.h"
+#include "mojo/public/cpp/bindings/lib/bindings_serialization.h"
+#include "mojo/public/cpp/bindings/lib/bounds_checker.h"
+#include "mojo/public/cpp/bindings/lib/buffer.h"
+#include "mojo/public/cpp/bindings/lib/validation_errors.h"
+
+namespace mojo {
+template <typename T> class Array;
+class String;
+
+namespace internal {
+
+template <typename T>
+struct ArrayDataTraits {
+ typedef T StorageType;
+ typedef T& Ref;
+ typedef T const& ConstRef;
+
+ static size_t GetStorageSize(size_t num_elements) {
+ return sizeof(StorageType) * num_elements;
+ }
+ static Ref ToRef(StorageType* storage, size_t offset) {
+ return storage[offset];
+ }
+ static ConstRef ToConstRef(const StorageType* storage, size_t offset) {
+ return storage[offset];
+ }
+};
+
+template <typename P>
+struct ArrayDataTraits<P*> {
+ typedef StructPointer<P> StorageType;
+ typedef P*& Ref;
+ typedef P* const& ConstRef;
+
+ static size_t GetStorageSize(size_t num_elements) {
+ return sizeof(StorageType) * num_elements;
+ }
+ static Ref ToRef(StorageType* storage, size_t offset) {
+ return storage[offset].ptr;
+ }
+ static ConstRef ToConstRef(const StorageType* storage, size_t offset) {
+ return storage[offset].ptr;
+ }
+};
+
+template <typename T>
+struct ArrayDataTraits<Array_Data<T>*> {
+ typedef ArrayPointer<T> StorageType;
+ typedef Array_Data<T>*& Ref;
+ typedef Array_Data<T>* const& ConstRef;
+
+ static size_t GetStorageSize(size_t num_elements) {
+ return sizeof(StorageType) * num_elements;
+ }
+ static Ref ToRef(StorageType* storage, size_t offset) {
+ return storage[offset].ptr;
+ }
+ static ConstRef ToConstRef(const StorageType* storage, size_t offset) {
+ return storage[offset].ptr;
+ }
+};
+
+// Specialization of Arrays for bools, optimized for space. It has the
+// following differences from a generalized Array:
+// * Each element takes up a single bit of memory.
+// * Accessing a non-const single element uses a helper class |BitRef|, which
+// emulates a reference to a bool.
+template <>
+struct ArrayDataTraits<bool> {
+ // Helper class to emulate a reference to a bool, used for direct element
+ // access.
+ class BitRef {
+ public:
+ ~BitRef();
+ BitRef& operator=(bool value);
+ BitRef& operator=(const BitRef& value);
+ operator bool() const;
+ private:
+ friend struct ArrayDataTraits<bool>;
+ BitRef(uint8_t* storage, uint8_t mask);
+ BitRef();
+ uint8_t* storage_;
+ uint8_t mask_;
+ };
+
+ typedef uint8_t StorageType;
+ typedef BitRef Ref;
+ typedef bool ConstRef;
+
+ static size_t GetStorageSize(size_t num_elements) {
+ return ((num_elements + 7) / 8);
+ }
+ static BitRef ToRef(StorageType* storage, size_t offset) {
+ return BitRef(&storage[offset / 8], 1 << (offset % 8));
+ }
+ static bool ToConstRef(const StorageType* storage, size_t offset) {
+ return (storage[offset / 8] & (1 << (offset % 8))) != 0;
+ }
+};
+
+// What follows is code to support the serialization of Array_Data<T>. There
+// are two interesting cases: arrays of primitives and arrays of objects.
+// Arrays of objects are represented as arrays of pointers to objects.
+
+template <typename T, bool kIsHandle> struct ArraySerializationHelper;
+
+template <typename T>
+struct ArraySerializationHelper<T, false> {
+ typedef typename ArrayDataTraits<T>::StorageType ElementType;
+
+ static void EncodePointersAndHandles(const ArrayHeader* header,
+ ElementType* elements,
+ std::vector<Handle>* handles) {
+ }
+
+ static void DecodePointersAndHandles(const ArrayHeader* header,
+ ElementType* elements,
+ std::vector<Handle>* handles) {
+ }
+
+ static bool ValidateElements(const ArrayHeader* header,
+ const ElementType* elements,
+ BoundsChecker* bounds_checker) {
+ return true;
+ }
+};
+
+template <>
+struct ArraySerializationHelper<Handle, true> {
+ typedef ArrayDataTraits<Handle>::StorageType ElementType;
+
+ static void EncodePointersAndHandles(const ArrayHeader* header,
+ ElementType* elements,
+ std::vector<Handle>* handles);
+
+ static void DecodePointersAndHandles(const ArrayHeader* header,
+ ElementType* elements,
+ std::vector<Handle>* handles);
+
+ static bool ValidateElements(const ArrayHeader* header,
+ const ElementType* elements,
+ BoundsChecker* bounds_checker);
+};
+
+template <typename H>
+struct ArraySerializationHelper<H, true> {
+ typedef typename ArrayDataTraits<H>::StorageType ElementType;
+
+ static void EncodePointersAndHandles(const ArrayHeader* header,
+ ElementType* elements,
+ std::vector<Handle>* handles) {
+ ArraySerializationHelper<Handle, true>::EncodePointersAndHandles(
+ header, elements, handles);
+ }
+
+ static void DecodePointersAndHandles(const ArrayHeader* header,
+ ElementType* elements,
+ std::vector<Handle>* handles) {
+ ArraySerializationHelper<Handle, true>::DecodePointersAndHandles(
+ header, elements, handles);
+ }
+
+ static bool ValidateElements(const ArrayHeader* header,
+ const ElementType* elements,
+ BoundsChecker* bounds_checker) {
+ return ArraySerializationHelper<Handle, true>::ValidateElements(
+ header, elements, bounds_checker);
+ }
+};
+
+template <typename P>
+struct ArraySerializationHelper<P*, false> {
+ typedef typename ArrayDataTraits<P*>::StorageType ElementType;
+
+ static void EncodePointersAndHandles(const ArrayHeader* header,
+ ElementType* elements,
+ std::vector<Handle>* handles) {
+ for (uint32_t i = 0; i < header->num_elements; ++i)
+ Encode(&elements[i], handles);
+ }
+
+ static void DecodePointersAndHandles(const ArrayHeader* header,
+ ElementType* elements,
+ std::vector<Handle>* handles) {
+ for (uint32_t i = 0; i < header->num_elements; ++i)
+ Decode(&elements[i], handles);
+ }
+
+ static bool ValidateElements(const ArrayHeader* header,
+ const ElementType* elements,
+ BoundsChecker* bounds_checker) {
+ for (uint32_t i = 0; i < header->num_elements; ++i) {
+ if (!ValidateEncodedPointer(&elements[i].offset)) {
+ ReportValidationError(VALIDATION_ERROR_ILLEGAL_POINTER);
+ return false;
+ }
+ if (!P::Validate(DecodePointerRaw(&elements[i].offset), bounds_checker))
+ return false;
+ }
+ return true;
+ }
+};
+
+template <typename T>
+class Array_Data {
+ public:
+ typedef ArrayDataTraits<T> Traits;
+ typedef typename Traits::StorageType StorageType;
+ typedef typename Traits::Ref Ref;
+ typedef typename Traits::ConstRef ConstRef;
+ typedef ArraySerializationHelper<T, IsHandle<T>::value> Helper;
+
+ static Array_Data<T>* New(size_t num_elements, Buffer* buf) {
+ size_t num_bytes = sizeof(Array_Data<T>) +
+ Traits::GetStorageSize(num_elements);
+ return new (buf->Allocate(num_bytes)) Array_Data<T>(num_bytes,
+ num_elements);
+ }
+
+ static bool Validate(const void* data, BoundsChecker* bounds_checker) {
+ if (!data)
+ return true;
+ if (!IsAligned(data)) {
+ ReportValidationError(VALIDATION_ERROR_MISALIGNED_OBJECT);
+ return false;
+ }
+ if (!bounds_checker->IsValidRange(data, sizeof(ArrayHeader))) {
+ ReportValidationError(VALIDATION_ERROR_ILLEGAL_MEMORY_RANGE);
+ return false;
+ }
+ const ArrayHeader* header = static_cast<const ArrayHeader*>(data);
+ if (header->num_bytes < (sizeof(Array_Data<T>) +
+ Traits::GetStorageSize(header->num_elements))) {
+ ReportValidationError(VALIDATION_ERROR_UNEXPECTED_ARRAY_HEADER);
+ return false;
+ }
+ if (!bounds_checker->ClaimMemory(data, header->num_bytes)) {
+ ReportValidationError(VALIDATION_ERROR_ILLEGAL_MEMORY_RANGE);
+ return false;
+ }
+
+ const Array_Data<T>* object = static_cast<const Array_Data<T>*>(data);
+ return Helper::ValidateElements(&object->header_, object->storage(),
+ bounds_checker);
+ }
+
+ size_t size() const { return header_.num_elements; }
+
+ Ref at(size_t offset) {
+ assert(offset < static_cast<size_t>(header_.num_elements));
+ return Traits::ToRef(storage(), offset);
+ }
+
+ ConstRef at(size_t offset) const {
+ assert(offset < static_cast<size_t>(header_.num_elements));
+ return Traits::ToConstRef(storage(), offset);
+ }
+
+ StorageType* storage() {
+ return reinterpret_cast<StorageType*>(
+ reinterpret_cast<char*>(this) + sizeof(*this));
+ }
+
+ const StorageType* storage() const {
+ return reinterpret_cast<const StorageType*>(
+ reinterpret_cast<const char*>(this) + sizeof(*this));
+ }
+
+ void EncodePointersAndHandles(std::vector<Handle>* handles) {
+ Helper::EncodePointersAndHandles(&header_, storage(), handles);
+ }
+
+ void DecodePointersAndHandles(std::vector<Handle>* handles) {
+ Helper::DecodePointersAndHandles(&header_, storage(), handles);
+ }
+
+ private:
+ Array_Data(size_t num_bytes, size_t num_elements) {
+ header_.num_bytes = static_cast<uint32_t>(num_bytes);
+ header_.num_elements = static_cast<uint32_t>(num_elements);
+ }
+ ~Array_Data() {}
+
+ internal::ArrayHeader header_;
+
+ // Elements of type internal::ArrayDataTraits<T>::StorageType follow.
+};
+MOJO_COMPILE_ASSERT(sizeof(Array_Data<char>) == 8, bad_sizeof_Array_Data);
+
+// UTF-8 encoded
+typedef Array_Data<char> String_Data;
+
+template <typename T, bool kIsMoveOnlyType> struct ArrayTraits {};
+
+template <typename T> struct ArrayTraits<T, false> {
+ typedef T StorageType;
+ typedef typename std::vector<T>::reference RefType;
+ typedef typename std::vector<T>::const_reference ConstRefType;
+ typedef ConstRefType ForwardType;
+ static inline void Initialize(std::vector<T>* vec) {
+ }
+ static inline void Finalize(std::vector<T>* vec) {
+ }
+ static inline ConstRefType at(const std::vector<T>* vec, size_t offset) {
+ return vec->at(offset);
+ }
+ static inline RefType at(std::vector<T>* vec, size_t offset) {
+ return vec->at(offset);
+ }
+ static inline void Resize(std::vector<T>* vec, size_t size) {
+ vec->resize(size);
+ }
+ static inline void PushBack(std::vector<T>* vec, ForwardType value) {
+ vec->push_back(value);
+ }
+};
+
+template <typename T> struct ArrayTraits<T, true> {
+ struct StorageType {
+ char buf[sizeof(T) + (8 - (sizeof(T) % 8)) % 8]; // Make 8-byte aligned.
+ };
+ typedef T& RefType;
+ typedef const T& ConstRefType;
+ typedef T ForwardType;
+ static inline void Initialize(std::vector<StorageType>* vec) {
+ for (size_t i = 0; i < vec->size(); ++i)
+ new (vec->at(i).buf) T();
+ }
+ static inline void Finalize(std::vector<StorageType>* vec) {
+ for (size_t i = 0; i < vec->size(); ++i)
+ reinterpret_cast<T*>(vec->at(i).buf)->~T();
+ }
+ static inline ConstRefType at(const std::vector<StorageType>* vec,
+ size_t offset) {
+ return *reinterpret_cast<const T*>(vec->at(offset).buf);
+ }
+ static inline RefType at(std::vector<StorageType>* vec, size_t offset) {
+ return *reinterpret_cast<T*>(vec->at(offset).buf);
+ }
+ static inline void Resize(std::vector<StorageType>* vec, size_t size) {
+ size_t old_size = vec->size();
+ for (size_t i = size; i < old_size; i++)
+ reinterpret_cast<T*>(vec->at(i).buf)->~T();
+ ResizeStorage(vec, size);
+ for (size_t i = old_size; i < vec->size(); i++)
+ new (vec->at(i).buf) T();
+ }
+ static inline void PushBack(std::vector<StorageType>* vec, RefType value) {
+ size_t old_size = vec->size();
+ ResizeStorage(vec, old_size + 1);
+ new (vec->at(old_size).buf) T(value.Pass());
+ }
+ static inline void ResizeStorage(std::vector<StorageType>* vec, size_t size) {
+ if (size <= vec->capacity()) {
+ vec->resize(size);
+ return;
+ }
+ std::vector<StorageType> new_storage(size);
+ for (size_t i = 0; i < vec->size(); i++)
+ new (new_storage.at(i).buf) T(at(vec, i).Pass());
+ vec->swap(new_storage);
+ Finalize(&new_storage);
+ }
+};
+
+template <> struct WrapperTraits<String, false> {
+ typedef String_Data* DataType;
+};
+
+} // namespace internal
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_INTERNAL_H_
diff --git a/chromium/mojo/public/cpp/bindings/lib/array_serialization.h b/chromium/mojo/public/cpp/bindings/lib/array_serialization.h
new file mode 100644
index 00000000000..83403d52502
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/array_serialization.h
@@ -0,0 +1,179 @@
+// 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.
+
+#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_SERIALIZATION_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_SERIALIZATION_H_
+
+#include <string>
+
+#include "mojo/public/cpp/bindings/lib/array_internal.h"
+#include "mojo/public/cpp/bindings/lib/string_serialization.h"
+
+namespace mojo {
+
+template <typename E>
+inline size_t GetSerializedSize_(const Array<E>& input);
+
+template <typename E, typename F>
+inline void Serialize_(Array<E> input, internal::Buffer* buf,
+ internal::Array_Data<F>** output);
+template <typename E, typename F>
+inline void Deserialize_(internal::Array_Data<F>* data, Array<E>* output);
+
+namespace internal {
+
+template <typename E, typename F, bool move_only = IsMoveOnlyType<E>::value>
+struct ArraySerializer;
+
+template <typename E, typename F> struct ArraySerializer<E, F, false> {
+ MOJO_COMPILE_ASSERT(sizeof(E) == sizeof(F), wrong_array_serializer);
+ static size_t GetSerializedSize(const Array<E>& input) {
+ return sizeof(Array_Data<F>) + Align(input.size() * sizeof(E));
+ }
+ static void SerializeElements(
+ Array<E> input, Buffer* buf, Array_Data<F>* output) {
+ memcpy(output->storage(), &input.storage()[0], input.size() * sizeof(E));
+ }
+ static void DeserializeElements(
+ Array_Data<F>* input, Array<E>* output) {
+ std::vector<E> result(input->size());
+ memcpy(&result[0], input->storage(), input->size() * sizeof(E));
+ output->Swap(&result);
+ }
+};
+
+template <> struct ArraySerializer<bool, bool, false> {
+ static size_t GetSerializedSize(const Array<bool>& input) {
+ return sizeof(Array_Data<bool>) + Align((input.size() + 7) / 8);
+ }
+ static void SerializeElements(
+ Array<bool> input, Buffer* buf, Array_Data<bool>* output) {
+ // TODO(darin): Can this be a memcpy somehow instead of a bit-by-bit copy?
+ for (size_t i = 0; i < input.size(); ++i)
+ output->at(i) = input[i];
+ }
+ static void DeserializeElements(
+ Array_Data<bool>* input, Array<bool>* output) {
+ Array<bool> result(input->size());
+ // TODO(darin): Can this be a memcpy somehow instead of a bit-by-bit copy?
+ for (size_t i = 0; i < input->size(); ++i)
+ result.at(i) = input->at(i);
+ output->Swap(&result);
+ }
+};
+
+template <typename H> struct ArraySerializer<ScopedHandleBase<H>, H, true> {
+ static size_t GetSerializedSize(const Array<ScopedHandleBase<H> >& input) {
+ return sizeof(Array_Data<H>) + Align(input.size() * sizeof(H));
+ }
+ static void SerializeElements(
+ Array<ScopedHandleBase<H> > input,
+ Buffer* buf,
+ Array_Data<H>* output) {
+ for (size_t i = 0; i < input.size(); ++i)
+ output->at(i) = input[i].release(); // Transfer ownership of the handle.
+ }
+ static void DeserializeElements(
+ Array_Data<H>* input, Array<ScopedHandleBase<H> >* output) {
+ Array<ScopedHandleBase<H> > result(input->size());
+ for (size_t i = 0; i < input->size(); ++i)
+ result.at(i) = MakeScopedHandle(FetchAndReset(&input->at(i)));
+ output->Swap(&result);
+ }
+};
+
+template <typename S> struct ArraySerializer<S, typename S::Data_*, true> {
+ static size_t GetSerializedSize(const Array<S>& input) {
+ size_t size = sizeof(Array_Data<typename S::Data_*>) +
+ input.size() * sizeof(internal::StructPointer<typename S::Data_>);
+ for (size_t i = 0; i < input.size(); ++i)
+ size += GetSerializedSize_(input[i]);
+ return size;
+ }
+ static void SerializeElements(
+ Array<S> input,
+ Buffer* buf,
+ Array_Data<typename S::Data_*>* output) {
+ for (size_t i = 0; i < input.size(); ++i) {
+ typename S::Data_* element;
+ Serialize_(input[i].Pass(), buf, &element);
+ output->at(i) = element;
+ }
+ }
+ static void DeserializeElements(
+ Array_Data<typename S::Data_*>* input, Array<S>* output) {
+ Array<S> result(input->size());
+ for (size_t i = 0; i < input->size(); ++i) {
+ S element;
+ Deserialize_(input->at(i), &element);
+ result[i] = element.Pass();
+ }
+ output->Swap(&result);
+ }
+};
+
+template <> struct ArraySerializer<String, String_Data*, false> {
+ static size_t GetSerializedSize(const Array<String>& input) {
+ size_t size = sizeof(Array_Data<String_Data*>) +
+ input.size() * sizeof(internal::StringPointer);
+ for (size_t i = 0; i < input.size(); ++i)
+ size += GetSerializedSize_(input[i]);
+ return size;
+ }
+ static void SerializeElements(
+ Array<String> input,
+ Buffer* buf,
+ Array_Data<String_Data*>* output) {
+ for (size_t i = 0; i < input.size(); ++i) {
+ String_Data* element;
+ Serialize_(input[i], buf, &element);
+ output->at(i) = element;
+ }
+ }
+ static void DeserializeElements(
+ Array_Data<String_Data*>* input, Array<String>* output) {
+ Array<String> result(input->size());
+ for (size_t i = 0; i < input->size(); ++i)
+ Deserialize_(input->at(i), &result[i]);
+ output->Swap(&result);
+ }
+};
+
+} // namespace internal
+
+template <typename E>
+inline size_t GetSerializedSize_(const Array<E>& input) {
+ if (!input)
+ return 0;
+ typedef typename internal::WrapperTraits<E>::DataType F;
+ return internal::ArraySerializer<E, F>::GetSerializedSize(input);
+}
+
+template <typename E, typename F>
+inline void Serialize_(Array<E> input, internal::Buffer* buf,
+ internal::Array_Data<F>** output) {
+ if (input) {
+ internal::Array_Data<F>* result =
+ internal::Array_Data<F>::New(input.size(), buf);
+ internal::ArraySerializer<E, F>::SerializeElements(
+ internal::Forward(input), buf, result);
+ *output = result;
+ } else {
+ *output = NULL;
+ }
+}
+
+template <typename E, typename F>
+inline void Deserialize_(internal::Array_Data<F>* input,
+ Array<E>* output) {
+ if (input) {
+ internal::ArraySerializer<E, F>::DeserializeElements(input, output);
+ } else {
+ output->reset();
+ }
+}
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_SERIALIZATION_H_
diff --git a/chromium/mojo/public/cpp/bindings/lib/bindings_internal.h b/chromium/mojo/public/cpp/bindings/lib/bindings_internal.h
new file mode 100644
index 00000000000..6e87cbd1fb5
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/bindings_internal.h
@@ -0,0 +1,86 @@
+// Copyright 2013 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.
+
+#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_BINDINGS_INTERNAL_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_LIB_BINDINGS_INTERNAL_H_
+
+#include "mojo/public/cpp/bindings/lib/template_util.h"
+#include "mojo/public/cpp/system/core.h"
+
+namespace mojo {
+class String;
+
+namespace internal {
+template <typename T> class Array_Data;
+
+#pragma pack(push, 1)
+
+struct StructHeader {
+ uint32_t num_bytes;
+ uint32_t num_fields;
+};
+MOJO_COMPILE_ASSERT(sizeof(StructHeader) == 8, bad_sizeof_StructHeader);
+
+struct ArrayHeader {
+ uint32_t num_bytes;
+ uint32_t num_elements;
+};
+MOJO_COMPILE_ASSERT(sizeof(ArrayHeader) == 8, bad_sizeof_ArrayHeader);
+
+template <typename T>
+union StructPointer {
+ uint64_t offset;
+ T* ptr;
+};
+MOJO_COMPILE_ASSERT(sizeof(StructPointer<char>) == 8, bad_sizeof_StructPointer);
+
+template <typename T>
+union ArrayPointer {
+ uint64_t offset;
+ Array_Data<T>* ptr;
+};
+MOJO_COMPILE_ASSERT(sizeof(ArrayPointer<char>) == 8, bad_sizeof_ArrayPointer);
+
+union StringPointer {
+ uint64_t offset;
+ Array_Data<char>* ptr;
+};
+MOJO_COMPILE_ASSERT(sizeof(StringPointer) == 8, bad_sizeof_StringPointer);
+
+#pragma pack(pop)
+
+template <typename T>
+void ResetIfNonNull(T* ptr) {
+ if (ptr)
+ *ptr = T();
+}
+
+template <typename T>
+T FetchAndReset(T* ptr) {
+ T temp = *ptr;
+ *ptr = T();
+ return temp;
+}
+
+template <typename H> struct IsHandle {
+ static const bool value = IsBaseOf<Handle, H>::value;
+};
+
+template <typename T, bool move_only = IsMoveOnlyType<T>::value>
+struct WrapperTraits;
+
+template <typename T> struct WrapperTraits<T, false> {
+ typedef T DataType;
+};
+template <typename H> struct WrapperTraits<ScopedHandleBase<H>, true> {
+ typedef H DataType;
+};
+template <typename S> struct WrapperTraits<S, true> {
+ typedef typename S::Data_* DataType;
+};
+
+} // namespace internal
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_BINDINGS_INTERNAL_H_
diff --git a/chromium/mojo/public/cpp/bindings/lib/bindings_serialization.cc b/chromium/mojo/public/cpp/bindings/lib/bindings_serialization.cc
new file mode 100644
index 00000000000..d5f77853684
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/bindings_serialization.cc
@@ -0,0 +1,118 @@
+// Copyright 2013 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/public/cpp/bindings/lib/bindings_serialization.h"
+
+#include <assert.h>
+
+#include "mojo/public/cpp/bindings/lib/bindings_internal.h"
+#include "mojo/public/cpp/bindings/lib/bounds_checker.h"
+#include "mojo/public/cpp/bindings/lib/validation_errors.h"
+
+namespace mojo {
+namespace internal {
+
+namespace {
+
+const size_t kAlignment = 8;
+
+template<typename T>
+T AlignImpl(T t) {
+ return t + (kAlignment - (t % kAlignment)) % kAlignment;
+}
+
+} // namespace
+
+size_t Align(size_t size) {
+ return AlignImpl(size);
+}
+
+char* AlignPointer(char* ptr) {
+ return reinterpret_cast<char*>(AlignImpl(reinterpret_cast<uintptr_t>(ptr)));
+}
+
+bool IsAligned(const void* ptr) {
+ return !(reinterpret_cast<uintptr_t>(ptr) % kAlignment);
+}
+
+void EncodePointer(const void* ptr, uint64_t* offset) {
+ if (!ptr) {
+ *offset = 0;
+ return;
+ }
+
+ const char* p_obj = reinterpret_cast<const char*>(ptr);
+ const char* p_slot = reinterpret_cast<const char*>(offset);
+ assert(p_obj > p_slot);
+
+ *offset = static_cast<uint64_t>(p_obj - p_slot);
+}
+
+const void* DecodePointerRaw(const uint64_t* offset) {
+ if (!*offset)
+ return NULL;
+ return reinterpret_cast<const char*>(offset) + *offset;
+}
+
+bool ValidateEncodedPointer(const uint64_t* offset) {
+ // Cast to uintptr_t so overflow behavior is well defined.
+ return reinterpret_cast<uintptr_t>(offset) + *offset >=
+ reinterpret_cast<uintptr_t>(offset);
+}
+
+void EncodeHandle(Handle* handle, std::vector<Handle>* handles) {
+ if (handle->is_valid()) {
+ handles->push_back(*handle);
+ handle->set_value(static_cast<MojoHandle>(handles->size() - 1));
+ } else {
+ handle->set_value(kEncodedInvalidHandleValue);
+ }
+}
+
+void DecodeHandle(Handle* handle, std::vector<Handle>* handles) {
+ if (handle->value() == kEncodedInvalidHandleValue) {
+ *handle = Handle();
+ return;
+ }
+ assert(handle->value() < handles->size());
+ // Just leave holes in the vector so we don't screw up other indices.
+ *handle = FetchAndReset(&handles->at(handle->value()));
+}
+
+bool ValidateStructHeader(const void* data,
+ uint32_t min_num_bytes,
+ uint32_t min_num_fields,
+ BoundsChecker* bounds_checker) {
+ assert(min_num_bytes >= sizeof(StructHeader));
+
+ if (!IsAligned(data)) {
+ ReportValidationError(VALIDATION_ERROR_MISALIGNED_OBJECT);
+ return false;
+ }
+ if (!bounds_checker->IsValidRange(data, sizeof(StructHeader))) {
+ ReportValidationError(VALIDATION_ERROR_ILLEGAL_MEMORY_RANGE);
+ return false;
+ }
+
+ const StructHeader* header = static_cast<const StructHeader*>(data);
+
+ // TODO(yzshen): Currently our binding code cannot handle structs of smaller
+ // size or with fewer fields than the version that it sees. That needs to be
+ // changed in order to provide backward compatibility.
+ if (header->num_bytes < min_num_bytes ||
+ header->num_fields < min_num_fields) {
+ ReportValidationError(VALIDATION_ERROR_UNEXPECTED_STRUCT_HEADER);
+ return false;
+ }
+
+ if (!bounds_checker->ClaimMemory(data, header->num_bytes)) {
+ ReportValidationError(VALIDATION_ERROR_ILLEGAL_MEMORY_RANGE);
+ return false;
+ }
+
+ return true;
+}
+
+} // namespace internal
+} // namespace mojo
diff --git a/chromium/mojo/public/cpp/bindings/lib/bindings_serialization.h b/chromium/mojo/public/cpp/bindings/lib/bindings_serialization.h
new file mode 100644
index 00000000000..6bebf90bf95
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/bindings_serialization.h
@@ -0,0 +1,83 @@
+// Copyright 2013 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.
+
+#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_BINDINGS_SERIALIZATION_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_LIB_BINDINGS_SERIALIZATION_H_
+
+#include <vector>
+
+#include "mojo/public/cpp/system/core.h"
+
+namespace mojo {
+namespace internal {
+
+class BoundsChecker;
+
+// Please note that this is a different value than |mojo::kInvalidHandleValue|,
+// which is the "decoded" invalid handle.
+const MojoHandle kEncodedInvalidHandleValue = static_cast<MojoHandle>(-1);
+
+size_t Align(size_t size);
+char* AlignPointer(char* ptr);
+
+bool IsAligned(const void* ptr);
+
+// Pointers are encoded as relative offsets. The offsets are relative to the
+// address of where the offset value is stored, such that the pointer may be
+// recovered with the expression:
+//
+// ptr = reinterpret_cast<char*>(offset) + *offset
+//
+// A null pointer is encoded as an offset value of 0.
+//
+void EncodePointer(const void* ptr, uint64_t* offset);
+// Note: This function doesn't validate the encoded pointer value.
+const void* DecodePointerRaw(const uint64_t* offset);
+
+// Note: This function doesn't validate the encoded pointer value.
+template <typename T>
+inline void DecodePointer(const uint64_t* offset, T** ptr) {
+ *ptr = reinterpret_cast<T*>(const_cast<void*>(DecodePointerRaw(offset)));
+}
+
+// Checks whether decoding the pointer will overflow and produce a pointer
+// smaller than |offset|.
+bool ValidateEncodedPointer(const uint64_t* offset);
+
+// Handles are encoded as indices into a vector of handles. These functions
+// manipulate the value of |handle|, mapping it to and from an index.
+void EncodeHandle(Handle* handle, std::vector<Handle>* handles);
+// Note: This function doesn't validate the encoded handle value.
+void DecodeHandle(Handle* handle, std::vector<Handle>* handles);
+
+// The following 2 functions are used to encode/decode all objects (structs and
+// arrays) in a consistent manner.
+
+template <typename T>
+inline void Encode(T* obj, std::vector<Handle>* handles) {
+ if (obj->ptr)
+ obj->ptr->EncodePointersAndHandles(handles);
+ EncodePointer(obj->ptr, &obj->offset);
+}
+
+// Note: This function doesn't validate the encoded pointer and handle values.
+template <typename T>
+inline void Decode(T* obj, std::vector<Handle>* handles) {
+ DecodePointer(&obj->offset, &obj->ptr);
+ if (obj->ptr)
+ obj->ptr->DecodePointersAndHandles(handles);
+}
+
+// If returns true, this function also claims the memory range of the size
+// specified in the struct header, starting from |data|.
+// Note: |min_num_bytes| must be no less than sizeof(StructHeader).
+bool ValidateStructHeader(const void* data,
+ uint32_t min_num_bytes,
+ uint32_t min_num_fields,
+ BoundsChecker* bounds_checker);
+
+} // namespace internal
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_BINDINGS_SERIALIZATION_H_
diff --git a/chromium/mojo/public/cpp/bindings/lib/bounds_checker.cc b/chromium/mojo/public/cpp/bindings/lib/bounds_checker.cc
new file mode 100644
index 00000000000..cf1f3238e03
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/bounds_checker.cc
@@ -0,0 +1,77 @@
+// 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/public/cpp/bindings/lib/bounds_checker.h"
+
+#include <assert.h>
+
+#include "mojo/public/cpp/bindings/lib/bindings_serialization.h"
+#include "mojo/public/cpp/system/core.h"
+
+namespace mojo {
+namespace internal {
+
+BoundsChecker::BoundsChecker(const void* data, uint32_t data_num_bytes,
+ size_t num_handles)
+ : data_begin_(reinterpret_cast<uintptr_t>(data)),
+ data_end_(data_begin_ + data_num_bytes),
+ handle_begin_(0),
+ handle_end_(static_cast<uint32_t>(num_handles)) {
+ if (data_end_ < data_begin_) {
+ // The calculation of |data_end_| overflowed.
+ // It shouldn't happen but if it does, set the range to empty so
+ // IsValidRange() and ClaimMemory() always fail.
+ assert(false); // Not reached.
+ data_end_ = data_begin_;
+ }
+ if (handle_end_ < num_handles) {
+ // Assigning |num_handles| to |handle_end_| overflowed.
+ // It shouldn't happen but if it does, set the handle index range to empty.
+ assert(false); // Not reached.
+ handle_end_ = 0;
+ }
+}
+
+BoundsChecker::~BoundsChecker() {
+}
+
+bool BoundsChecker::ClaimMemory(const void* position, uint32_t num_bytes) {
+ uintptr_t begin = reinterpret_cast<uintptr_t>(position);
+ uintptr_t end = begin + num_bytes;
+
+ if (!InternalIsValidRange(begin, end))
+ return false;
+
+ data_begin_ = end;
+ return true;
+}
+
+bool BoundsChecker::ClaimHandle(const Handle& encoded_handle) {
+ uint32_t index = encoded_handle.value();
+ if (index == kEncodedInvalidHandleValue)
+ return true;
+
+ if (index < handle_begin_ || index >= handle_end_)
+ return false;
+
+ // |index| + 1 shouldn't overflow, because |index| is not the max value of
+ // uint32_t (it is less than |handle_end_|).
+ handle_begin_ = index + 1;
+ return true;
+}
+
+bool BoundsChecker::IsValidRange(const void* position,
+ uint32_t num_bytes) const {
+ uintptr_t begin = reinterpret_cast<uintptr_t>(position);
+ uintptr_t end = begin + num_bytes;
+
+ return InternalIsValidRange(begin, end);
+}
+
+bool BoundsChecker::InternalIsValidRange(uintptr_t begin, uintptr_t end) const {
+ return end > begin && begin >= data_begin_ && end <= data_end_;
+}
+
+} // namespace internal
+} // namespace mojo
diff --git a/chromium/mojo/public/cpp/bindings/lib/bounds_checker.h b/chromium/mojo/public/cpp/bindings/lib/bounds_checker.h
new file mode 100644
index 00000000000..6c472309dde
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/bounds_checker.h
@@ -0,0 +1,64 @@
+// 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.
+
+#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_BOUNDS_CHECKER_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_LIB_BOUNDS_CHECKER_H_
+
+#include <stdint.h>
+
+#include "mojo/public/cpp/system/macros.h"
+
+namespace mojo {
+
+class Handle;
+
+namespace internal {
+
+// BoundsChecker is used to validate object sizes, pointers and handle indices
+// for payload of incoming messages.
+class BoundsChecker {
+ public:
+ // [data, data + data_num_bytes) specifies the initial valid memory range.
+ // [0, num_handles) specifies the initial valid range of handle indices.
+ BoundsChecker(const void* data, uint32_t data_num_bytes,
+ size_t num_handles);
+
+ ~BoundsChecker();
+
+ // Claims the specified memory range.
+ // The method succeeds if the range is valid to claim. (Please see
+ // the comments for IsValidRange().)
+ // On success, the valid memory range is shrinked to begin right after the end
+ // of the claimed range.
+ bool ClaimMemory(const void* position, uint32_t num_bytes);
+
+ // Claims the specified encoded handle (which is basically a handle index).
+ // The method succeeds if:
+ // - |encoded_handle|'s value is |kEncodedInvalidHandleValue|.
+ // - the handle is contained inside the valid range of handle indices. In this
+ // case, the valid range is shinked to begin right after the claimed handle.
+ bool ClaimHandle(const Handle& encoded_handle);
+
+ // Returns true if the specified range is not empty, and the range is
+ // contained inside the valid memory range.
+ bool IsValidRange(const void* position, uint32_t num_bytes) const;
+
+ private:
+ bool InternalIsValidRange(uintptr_t begin, uintptr_t end) const;
+
+ // [data_begin_, data_end_) is the valid memory range.
+ uintptr_t data_begin_;
+ uintptr_t data_end_;
+
+ // [handle_begin_, handle_end_) is the valid handle index range.
+ uint32_t handle_begin_;
+ uint32_t handle_end_;
+
+ MOJO_DISALLOW_COPY_AND_ASSIGN(BoundsChecker);
+};
+
+} // namespace internal
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_BOUNDS_CHECKER_H_
diff --git a/chromium/mojo/public/cpp/bindings/lib/buffer.h b/chromium/mojo/public/cpp/bindings/lib/buffer.h
new file mode 100644
index 00000000000..c3b570e7767
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/buffer.h
@@ -0,0 +1,24 @@
+// Copyright 2013 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.
+
+#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_BUFFER_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_LIB_BUFFER_H_
+
+#include <stddef.h>
+
+namespace mojo {
+namespace internal {
+
+// Buffer provides a way to allocate memory. Allocations are 8-byte aligned and
+// zero-initialized. Allocations remain valid for the lifetime of the Buffer.
+class Buffer {
+ public:
+ virtual ~Buffer() {}
+ virtual void* Allocate(size_t num_bytes) = 0;
+};
+
+} // namespace internal
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_BUFFER_H_
diff --git a/chromium/mojo/public/cpp/bindings/lib/callback_internal.h b/chromium/mojo/public/cpp/bindings/lib/callback_internal.h
new file mode 100644
index 00000000000..f76ebef59e6
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/callback_internal.h
@@ -0,0 +1,26 @@
+// 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.
+
+#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_CALLBACK_INTERNAL_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_LIB_CALLBACK_INTERNAL_H_
+
+namespace mojo {
+class String;
+
+namespace internal {
+
+template <typename T>
+struct Callback_ParamTraits {
+ typedef T ForwardType;
+};
+
+template <>
+struct Callback_ParamTraits<String> {
+ typedef const String& ForwardType;
+};
+
+} // namespace internal
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_CALLBACK_INTERNAL_H_
diff --git a/chromium/mojo/public/cpp/bindings/lib/connector.cc b/chromium/mojo/public/cpp/bindings/lib/connector.cc
new file mode 100644
index 00000000000..aa2c4d12334
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/connector.cc
@@ -0,0 +1,157 @@
+// Copyright 2013 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/public/cpp/bindings/lib/connector.h"
+
+#include <assert.h>
+#include <stdlib.h>
+
+#include "mojo/public/cpp/bindings/error_handler.h"
+
+namespace mojo {
+namespace internal {
+
+// ----------------------------------------------------------------------------
+
+Connector::Connector(ScopedMessagePipeHandle message_pipe,
+ const MojoAsyncWaiter* waiter)
+ : error_handler_(NULL),
+ waiter_(waiter),
+ message_pipe_(message_pipe.Pass()),
+ incoming_receiver_(NULL),
+ async_wait_id_(0),
+ error_(false),
+ drop_writes_(false),
+ enforce_errors_from_incoming_receiver_(true),
+ destroyed_flag_(NULL) {
+ // Even though we don't have an incoming receiver, we still want to monitor
+ // the message pipe to know if is closed or encounters an error.
+ WaitToReadMore();
+}
+
+Connector::~Connector() {
+ if (destroyed_flag_)
+ *destroyed_flag_ = true;
+
+ if (async_wait_id_)
+ waiter_->CancelWait(async_wait_id_);
+}
+
+void Connector::CloseMessagePipe() {
+ Close(message_pipe_.Pass());
+}
+
+ScopedMessagePipeHandle Connector::PassMessagePipe() {
+ if (async_wait_id_) {
+ waiter_->CancelWait(async_wait_id_);
+ async_wait_id_ = 0;
+ }
+ return message_pipe_.Pass();
+}
+
+bool Connector::Accept(Message* message) {
+ assert(message_pipe_.is_valid());
+
+ if (error_)
+ return false;
+
+ if (drop_writes_)
+ return true;
+
+ MojoResult rv = WriteMessageRaw(
+ message_pipe_.get(),
+ message->data(),
+ message->data_num_bytes(),
+ message->mutable_handles()->empty() ? NULL :
+ reinterpret_cast<const MojoHandle*>(
+ &message->mutable_handles()->front()),
+ static_cast<uint32_t>(message->mutable_handles()->size()),
+ MOJO_WRITE_MESSAGE_FLAG_NONE);
+
+ switch (rv) {
+ case MOJO_RESULT_OK:
+ // The handles were successfully transferred, so we don't need the message
+ // to track their lifetime any longer.
+ message->mutable_handles()->clear();
+ break;
+ case MOJO_RESULT_FAILED_PRECONDITION:
+ // There's no point in continuing to write to this pipe since the other
+ // end is gone. Avoid writing any future messages. Hide write failures
+ // from the caller since we'd like them to continue consuming any backlog
+ // of incoming messages before regarding the message pipe as closed.
+ drop_writes_ = true;
+ break;
+ default:
+ // This particular write was rejected, presumably because of bad input.
+ // The pipe is not necessarily in a bad state.
+ return false;
+ }
+ return true;
+}
+
+// static
+void Connector::CallOnHandleReady(void* closure, MojoResult result) {
+ Connector* self = static_cast<Connector*>(closure);
+ self->OnHandleReady(result);
+}
+
+void Connector::OnHandleReady(MojoResult result) {
+ assert(async_wait_id_ != 0);
+ async_wait_id_ = 0;
+
+ if (result == MOJO_RESULT_OK) {
+ // Return immediately if |this| was destroyed. Do not touch any members!
+ if (!ReadMore())
+ return;
+ } else {
+ error_ = true;
+ }
+
+ if (error_ && error_handler_)
+ error_handler_->OnConnectionError();
+}
+
+void Connector::WaitToReadMore() {
+ async_wait_id_ = waiter_->AsyncWait(message_pipe_.get().value(),
+ MOJO_HANDLE_SIGNAL_READABLE,
+ MOJO_DEADLINE_INDEFINITE,
+ &Connector::CallOnHandleReady,
+ this);
+}
+
+bool Connector::ReadMore() {
+ while (true) {
+ bool receiver_result = false;
+
+ // Detect if |this| was destroyed during message dispatch. Allow for the
+ // possibility of re-entering ReadMore() through message dispatch.
+ bool was_destroyed_during_dispatch = false;
+ bool* previous_destroyed_flag = destroyed_flag_;
+ destroyed_flag_ = &was_destroyed_during_dispatch;
+
+ MojoResult rv = ReadAndDispatchMessage(
+ message_pipe_.get(), incoming_receiver_, &receiver_result);
+
+ if (was_destroyed_during_dispatch) {
+ if (previous_destroyed_flag)
+ *previous_destroyed_flag = true; // Propagate flag.
+ return false;
+ }
+ destroyed_flag_ = previous_destroyed_flag;
+
+ if (rv == MOJO_RESULT_SHOULD_WAIT) {
+ WaitToReadMore();
+ break;
+ }
+ if (rv != MOJO_RESULT_OK ||
+ (enforce_errors_from_incoming_receiver_ && !receiver_result)) {
+ error_ = true;
+ break;
+ }
+ }
+ return true;
+}
+
+} // namespace internal
+} // namespace mojo
diff --git a/chromium/mojo/public/cpp/bindings/lib/connector.h b/chromium/mojo/public/cpp/bindings/lib/connector.h
new file mode 100644
index 00000000000..30cd65f4c42
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/connector.h
@@ -0,0 +1,100 @@
+// Copyright 2013 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.
+
+#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_CONNECTOR_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_LIB_CONNECTOR_H_
+
+#include "mojo/public/c/environment/async_waiter.h"
+#include "mojo/public/cpp/bindings/lib/message_queue.h"
+#include "mojo/public/cpp/bindings/message.h"
+#include "mojo/public/cpp/environment/environment.h"
+#include "mojo/public/cpp/system/core.h"
+
+namespace mojo {
+class ErrorHandler;
+
+namespace internal {
+
+// The Connector class is responsible for performing read/write operations on a
+// MessagePipe. It writes messages it receives through the MessageReceiver
+// interface that it subclasses, and it forwards messages it reads through the
+// MessageReceiver interface assigned as its incoming receiver.
+//
+// NOTE: MessagePipe I/O is non-blocking.
+//
+class Connector : public MessageReceiver {
+ public:
+ // The Connector takes ownership of |message_pipe|.
+ explicit Connector(
+ ScopedMessagePipeHandle message_pipe,
+ const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter());
+ virtual ~Connector();
+
+ // Sets the receiver to handle messages read from the message pipe. The
+ // Connector will read messages from the pipe regardless of whether or not an
+ // incoming receiver has been set.
+ void set_incoming_receiver(MessageReceiver* receiver) {
+ incoming_receiver_ = receiver;
+ }
+
+ // Errors from incoming receivers will force the connector into an error
+ // state, where no more messages will be processed. This method is used
+ // during testing to prevent that from happening.
+ void set_enforce_errors_from_incoming_receiver(bool enforce) {
+ enforce_errors_from_incoming_receiver_ = enforce;
+ }
+
+ // Sets the error handler to receive notifications when an error is
+ // encountered while reading from the pipe or waiting to read from the pipe.
+ void set_error_handler(ErrorHandler* error_handler) {
+ error_handler_ = error_handler;
+ }
+
+ // Returns true if an error was encountered while reading from the pipe or
+ // waiting to read from the pipe.
+ bool encountered_error() const { return error_; }
+
+ // Closes the pipe, triggering the error state. Connector is put into a
+ // quiescent state.
+ void CloseMessagePipe();
+
+ // Releases the pipe, not triggering the error state. Connector is put into
+ // a quiescent state.
+ ScopedMessagePipeHandle PassMessagePipe();
+
+ // MessageReceiver implementation:
+ virtual bool Accept(Message* message) MOJO_OVERRIDE;
+
+ private:
+ static void CallOnHandleReady(void* closure, MojoResult result);
+ void OnHandleReady(MojoResult result);
+
+ void WaitToReadMore();
+
+ // Returns false if |this| was destroyed during message dispatch.
+ MOJO_WARN_UNUSED_RESULT bool ReadMore();
+
+ ErrorHandler* error_handler_;
+ const MojoAsyncWaiter* waiter_;
+
+ ScopedMessagePipeHandle message_pipe_;
+ MessageReceiver* incoming_receiver_;
+
+ MojoAsyncWaitID async_wait_id_;
+ bool error_;
+ bool drop_writes_;
+ bool enforce_errors_from_incoming_receiver_;
+
+ // If non-null, this will be set to true when the Connector is destroyed. We
+ // use this flag to allow for the Connector to be destroyed as a side-effect
+ // of dispatching an incoming message.
+ bool* destroyed_flag_;
+
+ MOJO_DISALLOW_COPY_AND_ASSIGN(Connector);
+};
+
+} // namespace internal
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_CONNECTOR_H_
diff --git a/chromium/mojo/public/cpp/bindings/lib/filter_chain.cc b/chromium/mojo/public/cpp/bindings/lib/filter_chain.cc
new file mode 100644
index 00000000000..efd4ba19875
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/filter_chain.cc
@@ -0,0 +1,49 @@
+// 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/public/cpp/bindings/lib/filter_chain.h"
+
+#include <assert.h>
+
+#include <algorithm>
+
+namespace mojo {
+namespace internal {
+
+FilterChain::FilterChain(MessageReceiver* sink) : sink_(sink) {
+}
+
+FilterChain::FilterChain(RValue other) : sink_(other.object->sink_) {
+ other.object->sink_ = NULL;
+ filters_.swap(other.object->filters_);
+}
+
+FilterChain& FilterChain::operator=(RValue other) {
+ std::swap(sink_, other.object->sink_);
+ filters_.swap(other.object->filters_);
+ return *this;
+}
+
+FilterChain::~FilterChain() {
+ for (std::vector<MessageFilter*>::iterator iter = filters_.begin();
+ iter != filters_.end();
+ ++iter) {
+ delete *iter;
+ }
+}
+
+void FilterChain::SetSink(MessageReceiver* sink) {
+ assert(!sink_);
+ sink_ = sink;
+ if (!filters_.empty())
+ filters_.back()->set_sink(sink);
+}
+
+MessageReceiver* FilterChain::GetHead() {
+ assert(sink_);
+ return filters_.empty() ? sink_ : filters_.front();
+}
+
+} // namespace internal
+} // namespace mojo
diff --git a/chromium/mojo/public/cpp/bindings/lib/filter_chain.h b/chromium/mojo/public/cpp/bindings/lib/filter_chain.h
new file mode 100644
index 00000000000..8680f41aaee
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/filter_chain.h
@@ -0,0 +1,66 @@
+// 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.
+
+#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_FILTER_CHAIN_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_LIB_FILTER_CHAIN_H_
+
+#include <vector>
+
+#include "mojo/public/cpp/bindings/message.h"
+#include "mojo/public/cpp/bindings/message_filter.h"
+#include "mojo/public/cpp/system/macros.h"
+
+namespace mojo {
+namespace internal {
+
+class FilterChain {
+ MOJO_MOVE_ONLY_TYPE_FOR_CPP_03(FilterChain, RValue)
+
+ public:
+ // Doesn't take ownership of |sink|. Therefore |sink| has to stay alive while
+ // this object is alive.
+ explicit FilterChain(MessageReceiver* sink = NULL);
+
+ // Move-only constructor and operator=.
+ FilterChain(RValue other);
+ FilterChain& operator=(RValue other);
+
+ ~FilterChain();
+
+ template <typename FilterType>
+ inline void Append();
+
+ // Doesn't take ownership of |sink|. Therefore |sink| has to stay alive while
+ // this object is alive.
+ void SetSink(MessageReceiver* sink);
+
+ // Returns a receiver to accept messages. Messages flow through all filters in
+ // the same order as they were appended to the chain. If all filters allow a
+ // message to pass, it will be forwarded to |sink_|.
+ // The returned value is invalidated when this object goes away.
+ MessageReceiver* GetHead();
+
+ private:
+ // Owned by this object.
+ std::vector<MessageFilter*> filters_;
+
+ MessageReceiver* sink_;
+};
+
+template <typename FilterType>
+inline void FilterChain::Append() {
+ FilterType* filter = new FilterType(sink_);
+ if (!filters_.empty())
+ filters_.back()->set_sink(filter);
+ filters_.push_back(filter);
+}
+
+template <>
+inline void FilterChain::Append<PassThroughFilter>() {
+}
+
+} // namespace internal
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_FILTER_CHAIN_H_
diff --git a/chromium/mojo/public/cpp/bindings/lib/fixed_buffer.cc b/chromium/mojo/public/cpp/bindings/lib/fixed_buffer.cc
new file mode 100644
index 00000000000..5226231725c
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/fixed_buffer.cc
@@ -0,0 +1,53 @@
+// 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/public/cpp/bindings/lib/fixed_buffer.h"
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <algorithm>
+
+#include "mojo/public/cpp/bindings/lib/bindings_serialization.h"
+
+namespace mojo {
+namespace internal {
+
+FixedBuffer::FixedBuffer(size_t size)
+ : ptr_(NULL),
+ cursor_(0),
+ size_(internal::Align(size)) {
+ // calloc() required to zero memory and thus avoid info leaks.
+ ptr_ = static_cast<char*>(calloc(size_, 1));
+}
+
+FixedBuffer::~FixedBuffer() {
+ free(ptr_);
+}
+
+void* FixedBuffer::Allocate(size_t delta) {
+ delta = internal::Align(delta);
+
+ if (delta == 0 || delta > size_ - cursor_) {
+ assert(false);
+ return NULL;
+ }
+
+ char* result = ptr_ + cursor_;
+ cursor_ += delta;
+
+ return result;
+}
+
+void* FixedBuffer::Leak() {
+ char* ptr = ptr_;
+ ptr_ = NULL;
+ cursor_ = 0;
+ size_ = 0;
+ return ptr;
+}
+
+} // namespace internal
+} // namespace mojo
diff --git a/chromium/mojo/public/cpp/bindings/lib/fixed_buffer.h b/chromium/mojo/public/cpp/bindings/lib/fixed_buffer.h
new file mode 100644
index 00000000000..a3515a2ae86
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/fixed_buffer.h
@@ -0,0 +1,67 @@
+// 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.
+
+#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_FIXED_BUFFER_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_LIB_FIXED_BUFFER_H_
+
+#include "mojo/public/cpp/bindings/lib/buffer.h"
+#include "mojo/public/cpp/system/macros.h"
+
+namespace mojo {
+namespace internal {
+
+// FixedBuffer provides a simple way to allocate objects within a fixed chunk
+// of memory. Objects are allocated by calling the |Allocate| method, which
+// extends the buffer accordingly. Objects allocated in this way are not freed
+// explicitly. Instead, they remain valid so long as the FixedBuffer remains
+// valid. The Leak method may be used to steal the underlying memory from the
+// FixedBuffer.
+//
+// Typical usage:
+//
+// {
+// FixedBuffer buf(8 + 8);
+//
+// int* a = static_cast<int*>(buf->Allocate(sizeof(int)));
+// *a = 2;
+//
+// double* b = static_cast<double*>(buf->Allocate(sizeof(double)));
+// *b = 3.14f;
+//
+// void* data = buf.Leak();
+// Process(data);
+//
+// free(data);
+// }
+//
+class FixedBuffer : public Buffer {
+ public:
+ explicit FixedBuffer(size_t size);
+ virtual ~FixedBuffer();
+
+ // Grows the buffer by |num_bytes| and returns a pointer to the start of the
+ // addition. The resulting address is 8-byte aligned, and the content of the
+ // memory is zero-filled.
+ virtual void* Allocate(size_t num_bytes) MOJO_OVERRIDE;
+
+ size_t size() const { return size_; }
+
+ // Returns the internal memory owned by the Buffer to the caller. The Buffer
+ // relinquishes its pointer, effectively resetting the state of the Buffer
+ // and leaving the caller responsible for freeing the returned memory address
+ // when no longer needed.
+ void* Leak();
+
+ private:
+ char* ptr_;
+ size_t cursor_;
+ size_t size_;
+
+ MOJO_DISALLOW_COPY_AND_ASSIGN(FixedBuffer);
+};
+
+} // namespace internal
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_FIXED_BUFFER_H_
diff --git a/chromium/mojo/public/cpp/bindings/lib/interface_impl_internal.h b/chromium/mojo/public/cpp/bindings/lib/interface_impl_internal.h
new file mode 100644
index 00000000000..f2cc4f0c5b6
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/interface_impl_internal.h
@@ -0,0 +1,94 @@
+// 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.
+
+#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_INTERFACE_IMPL_INTERNAL_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_LIB_INTERFACE_IMPL_INTERNAL_H_
+
+#include "mojo/public/cpp/bindings/error_handler.h"
+#include "mojo/public/cpp/bindings/interface_ptr.h"
+#include "mojo/public/cpp/bindings/lib/filter_chain.h"
+#include "mojo/public/cpp/bindings/lib/message_header_validator.h"
+#include "mojo/public/cpp/environment/environment.h"
+#include "mojo/public/cpp/system/macros.h"
+
+namespace mojo {
+namespace internal {
+
+template <typename Interface>
+class InterfaceImplBase : public Interface {
+ public:
+ virtual ~InterfaceImplBase() {}
+ virtual void OnConnectionEstablished() = 0;
+ virtual void OnConnectionError() = 0;
+};
+
+template <typename Interface>
+class InterfaceImplState : public ErrorHandler {
+ public:
+ typedef typename Interface::Client Client;
+
+ explicit InterfaceImplState(InterfaceImplBase<Interface>* instance)
+ : router_(NULL),
+ proxy_(NULL) {
+ assert(instance);
+ stub_.set_sink(instance);
+ }
+
+ virtual ~InterfaceImplState() {
+ delete proxy_;
+ if (router_) {
+ router_->set_error_handler(NULL);
+ delete router_;
+ }
+ }
+
+ void BindProxy(
+ InterfacePtr<Interface>* ptr,
+ const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) {
+ MessagePipe pipe;
+ ptr->Bind(pipe.handle0.Pass(), waiter);
+ Bind(pipe.handle1.Pass(), waiter);
+ }
+
+ void Bind(ScopedMessagePipeHandle handle,
+ const MojoAsyncWaiter* waiter) {
+ assert(!router_);
+
+ FilterChain filters;
+ filters.Append<MessageHeaderValidator>();
+ filters.Append<typename Interface::RequestValidator_>();
+ filters.Append<typename Interface::Client::ResponseValidator_>();
+
+ router_ = new Router(handle.Pass(), filters.Pass(), waiter);
+ router_->set_incoming_receiver(&stub_);
+ router_->set_error_handler(this);
+
+ proxy_ = new typename Client::Proxy_(router_);
+
+ instance()->OnConnectionEstablished();
+ }
+
+ Router* router() { return router_; }
+ Client* client() { return proxy_; }
+
+ private:
+ InterfaceImplBase<Interface>* instance() {
+ return static_cast<InterfaceImplBase<Interface>*>(stub_.sink());
+ }
+
+ virtual void OnConnectionError() MOJO_OVERRIDE {
+ instance()->OnConnectionError();
+ }
+
+ Router* router_;
+ typename Client::Proxy_* proxy_;
+ typename Interface::Stub_ stub_;
+
+ MOJO_DISALLOW_COPY_AND_ASSIGN(InterfaceImplState);
+};
+
+} // namespace internal
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_INTERFACE_IMPL_INTERNAL_H_
diff --git a/chromium/mojo/public/cpp/bindings/lib/interface_ptr_internal.h b/chromium/mojo/public/cpp/bindings/lib/interface_ptr_internal.h
new file mode 100644
index 00000000000..a318d6185c5
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/interface_ptr_internal.h
@@ -0,0 +1,84 @@
+// 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.
+
+#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_INTERFACE_PTR_INTERNAL_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_LIB_INTERFACE_PTR_INTERNAL_H_
+
+#include <assert.h>
+#include <stdio.h>
+
+#include "mojo/public/cpp/bindings/lib/filter_chain.h"
+#include "mojo/public/cpp/bindings/lib/message_header_validator.h"
+#include "mojo/public/cpp/bindings/lib/router.h"
+#include "mojo/public/cpp/environment/environment.h"
+
+namespace mojo {
+namespace internal {
+
+template <typename Interface>
+class InterfacePtrState {
+ public:
+ InterfacePtrState() : proxy_(NULL), router_(NULL) {}
+
+ ~InterfacePtrState() {
+ // Destruction order matters here. We delete |proxy_| first, even though
+ // |router_| may have a reference to it, so that |~Interface| may have a
+ // shot at generating new outbound messages (ie, invoking client methods).
+ delete proxy_;
+ delete router_;
+ }
+
+ Interface* instance() const { return proxy_; }
+
+ Router* router() const { return router_; }
+
+ void Swap(InterfacePtrState* other) {
+ std::swap(other->proxy_, proxy_);
+ std::swap(other->router_, router_);
+ }
+
+ void ConfigureProxy(
+ ScopedMessagePipeHandle handle,
+ const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) {
+ assert(!proxy_);
+ assert(!router_);
+
+ FilterChain filters;
+ filters.Append<MessageHeaderValidator>();
+ filters.Append<typename Interface::Client::RequestValidator_>();
+ filters.Append<typename Interface::ResponseValidator_>();
+
+ router_ = new Router(handle.Pass(), filters.Pass(), waiter);
+ ProxyWithStub* proxy = new ProxyWithStub(router_);
+ router_->set_incoming_receiver(&proxy->stub);
+
+ proxy_ = proxy;
+ }
+
+ void set_client(typename Interface::Client* client) {
+ assert(proxy_);
+ proxy_->stub.set_sink(client);
+ }
+
+ private:
+ class ProxyWithStub : public Interface::Proxy_ {
+ public:
+ explicit ProxyWithStub(MessageReceiverWithResponder* receiver)
+ : Interface::Proxy_(receiver) {
+ }
+ typename Interface::Client::Stub_ stub;
+ private:
+ MOJO_DISALLOW_COPY_AND_ASSIGN(ProxyWithStub);
+ };
+
+ ProxyWithStub* proxy_;
+ Router* router_;
+
+ MOJO_DISALLOW_COPY_AND_ASSIGN(InterfacePtrState);
+};
+
+} // namespace internal
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_INTERFACE_PTR_INTERNAL_H_
diff --git a/chromium/mojo/public/cpp/bindings/lib/message.cc b/chromium/mojo/public/cpp/bindings/lib/message.cc
new file mode 100644
index 00000000000..78017c00793
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/message.cc
@@ -0,0 +1,81 @@
+// Copyright 2013 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/public/cpp/bindings/message.h"
+
+#include <assert.h>
+#include <stdlib.h>
+
+#include <algorithm>
+
+namespace mojo {
+
+Message::Message()
+ : data_num_bytes_(0),
+ data_(NULL) {
+}
+
+Message::~Message() {
+ free(data_);
+
+ for (std::vector<Handle>::iterator it = handles_.begin();
+ it != handles_.end(); ++it) {
+ if (it->is_valid())
+ CloseRaw(*it);
+ }
+}
+
+void Message::AllocUninitializedData(uint32_t num_bytes) {
+ assert(!data_);
+ data_num_bytes_ = num_bytes;
+ data_ = static_cast<internal::MessageData*>(malloc(num_bytes));
+}
+
+void Message::AdoptData(uint32_t num_bytes, internal::MessageData* data) {
+ assert(!data_);
+ data_num_bytes_ = num_bytes;
+ data_ = data;
+}
+
+void Message::Swap(Message* other) {
+ std::swap(data_num_bytes_, other->data_num_bytes_);
+ std::swap(data_, other->data_);
+ std::swap(handles_, other->handles_);
+}
+
+MojoResult ReadAndDispatchMessage(MessagePipeHandle handle,
+ MessageReceiver* receiver,
+ bool* receiver_result) {
+ MojoResult rv;
+
+ uint32_t num_bytes = 0, num_handles = 0;
+ rv = ReadMessageRaw(handle,
+ NULL,
+ &num_bytes,
+ NULL,
+ &num_handles,
+ MOJO_READ_MESSAGE_FLAG_NONE);
+ if (rv != MOJO_RESULT_RESOURCE_EXHAUSTED)
+ return rv;
+
+ Message message;
+ message.AllocUninitializedData(num_bytes);
+ message.mutable_handles()->resize(num_handles);
+
+ rv = ReadMessageRaw(handle,
+ message.mutable_data(),
+ &num_bytes,
+ message.mutable_handles()->empty()
+ ? NULL
+ : reinterpret_cast<MojoHandle*>(
+ &message.mutable_handles()->front()),
+ &num_handles,
+ MOJO_READ_MESSAGE_FLAG_NONE);
+ if (receiver && rv == MOJO_RESULT_OK)
+ *receiver_result = receiver->Accept(&message);
+
+ return rv;
+}
+
+} // namespace mojo
diff --git a/chromium/mojo/public/cpp/bindings/lib/message_builder.cc b/chromium/mojo/public/cpp/bindings/lib/message_builder.cc
new file mode 100644
index 00000000000..c7466444d04
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/message_builder.cc
@@ -0,0 +1,52 @@
+// Copyright 2013 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/public/cpp/bindings/lib/message_builder.h"
+
+#include "mojo/public/cpp/bindings/message.h"
+
+namespace mojo {
+namespace internal {
+
+template <typename Header>
+void Allocate(Buffer* buf, Header** header) {
+ *header = static_cast<Header*>(buf->Allocate(sizeof(Header)));
+ (*header)->num_bytes = sizeof(Header);
+}
+
+MessageBuilder::MessageBuilder(uint32_t name, size_t payload_size)
+ : buf_(sizeof(MessageHeader) + payload_size) {
+ MessageHeader* header;
+ Allocate(&buf_, &header);
+ header->num_fields = 2;
+ header->name = name;
+}
+
+MessageBuilder::~MessageBuilder() {
+}
+
+void MessageBuilder::Finish(Message* message) {
+ uint32_t num_bytes = static_cast<uint32_t>(buf_.size());
+ message->AdoptData(num_bytes, static_cast<MessageData*>(buf_.Leak()));
+}
+
+MessageBuilder::MessageBuilder(size_t size)
+ : buf_(size) {
+}
+
+MessageWithRequestIDBuilder::MessageWithRequestIDBuilder(uint32_t name,
+ size_t payload_size,
+ uint32_t flags,
+ uint64_t request_id)
+ : MessageBuilder(sizeof(MessageHeaderWithRequestID) + payload_size) {
+ MessageHeaderWithRequestID* header;
+ Allocate(&buf_, &header);
+ header->num_fields = 3;
+ header->name = name;
+ header->flags = flags;
+ header->request_id = request_id;
+}
+
+} // namespace internal
+} // namespace mojo
diff --git a/chromium/mojo/public/cpp/bindings/lib/message_builder.h b/chromium/mojo/public/cpp/bindings/lib/message_builder.h
new file mode 100644
index 00000000000..b4988ff9cb9
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/message_builder.h
@@ -0,0 +1,63 @@
+// Copyright 2013 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.
+
+#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_MESSAGE_BUILDER_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_LIB_MESSAGE_BUILDER_H_
+
+#include <stdint.h>
+
+#include "mojo/public/cpp/bindings/lib/fixed_buffer.h"
+#include "mojo/public/cpp/bindings/lib/message_internal.h"
+
+namespace mojo {
+class Message;
+
+namespace internal {
+
+class MessageBuilder {
+ public:
+ MessageBuilder(uint32_t name, size_t payload_size);
+ ~MessageBuilder();
+
+ Buffer* buffer() { return &buf_; }
+
+ // Call Finish when done making allocations in |buffer()|. Upon return,
+ // |message| will contain the message data, and |buffer()| will no longer be
+ // valid to reference.
+ void Finish(Message* message);
+
+ protected:
+ explicit MessageBuilder(size_t size);
+ FixedBuffer buf_;
+
+ MOJO_DISALLOW_COPY_AND_ASSIGN(MessageBuilder);
+};
+
+class MessageWithRequestIDBuilder : public MessageBuilder {
+ public:
+ MessageWithRequestIDBuilder(uint32_t name, size_t payload_size,
+ uint32_t flags, uint64_t request_id);
+};
+
+class RequestMessageBuilder : public MessageWithRequestIDBuilder {
+ public:
+ RequestMessageBuilder(uint32_t name, size_t payload_size)
+ : MessageWithRequestIDBuilder(name, payload_size, kMessageExpectsResponse,
+ 0) {
+ }
+};
+
+class ResponseMessageBuilder : public MessageWithRequestIDBuilder {
+ public:
+ ResponseMessageBuilder(uint32_t name, size_t payload_size,
+ uint64_t request_id)
+ : MessageWithRequestIDBuilder(name, payload_size, kMessageIsResponse,
+ request_id) {
+ }
+};
+
+} // namespace internal
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_MESSAGE_BUILDER_H_
diff --git a/chromium/mojo/public/cpp/bindings/lib/message_filter.cc b/chromium/mojo/public/cpp/bindings/lib/message_filter.cc
new file mode 100644
index 00000000000..b09f40d8c5e
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/message_filter.cc
@@ -0,0 +1,23 @@
+// 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/public/cpp/bindings/message_filter.h"
+
+namespace mojo {
+
+MessageFilter::MessageFilter(MessageReceiver* sink) : sink_(sink) {
+}
+
+MessageFilter::~MessageFilter() {
+}
+
+PassThroughFilter::PassThroughFilter(MessageReceiver* sink)
+ : MessageFilter(sink) {
+}
+
+bool PassThroughFilter::Accept(Message* message) {
+ return sink_->Accept(message);
+}
+
+} // namespace mojo
diff --git a/chromium/mojo/public/cpp/bindings/lib/message_header_validator.cc b/chromium/mojo/public/cpp/bindings/lib/message_header_validator.cc
new file mode 100644
index 00000000000..a55917afde5
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/message_header_validator.cc
@@ -0,0 +1,81 @@
+// 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/public/cpp/bindings/lib/message_header_validator.h"
+
+#include "mojo/public/cpp/bindings/lib/bindings_serialization.h"
+#include "mojo/public/cpp/bindings/lib/bounds_checker.h"
+#include "mojo/public/cpp/bindings/lib/validation_errors.h"
+
+namespace mojo {
+namespace internal {
+namespace {
+
+bool IsValidMessageHeader(const MessageHeader* header) {
+ // NOTE: Our goal is to preserve support for future extension of the message
+ // header. If we encounter fields we do not understand, we must ignore them.
+
+ // Extra validation of the struct header:
+ if (header->num_fields == 2) {
+ if (header->num_bytes != sizeof(MessageHeader)) {
+ ReportValidationError(VALIDATION_ERROR_UNEXPECTED_STRUCT_HEADER);
+ return false;
+ }
+ } else if (header->num_fields == 3) {
+ if (header->num_bytes != sizeof(MessageHeaderWithRequestID)) {
+ ReportValidationError(VALIDATION_ERROR_UNEXPECTED_STRUCT_HEADER);
+ return false;
+ }
+ } else if (header->num_fields > 3) {
+ if (header->num_bytes < sizeof(MessageHeaderWithRequestID)) {
+ ReportValidationError(VALIDATION_ERROR_UNEXPECTED_STRUCT_HEADER);
+ return false;
+ }
+ }
+
+ // Validate flags (allow unknown bits):
+
+ // These flags require a RequestID.
+ if (header->num_fields < 3 &&
+ ((header->flags & kMessageExpectsResponse) ||
+ (header->flags & kMessageIsResponse))) {
+ ReportValidationError(VALIDATION_ERROR_MESSAGE_HEADER_MISSING_REQUEST_ID);
+ return false;
+ }
+
+ // These flags are mutually exclusive.
+ if ((header->flags & kMessageExpectsResponse) &&
+ (header->flags & kMessageIsResponse)) {
+ ReportValidationError(
+ VALIDATION_ERROR_MESSAGE_HEADER_INVALID_FLAG_COMBINATION);
+ return false;
+ }
+
+ return true;
+}
+
+} // namespace
+
+MessageHeaderValidator::MessageHeaderValidator(MessageReceiver* sink)
+ : MessageFilter(sink) {
+}
+
+bool MessageHeaderValidator::Accept(Message* message) {
+ // Pass 0 as number of handles because we don't expect any in the header, even
+ // if |message| contains handles.
+ BoundsChecker bounds_checker(message->data(), message->data_num_bytes(), 0);
+
+ if (!ValidateStructHeader(message->data(), sizeof(MessageHeader), 2,
+ &bounds_checker)) {
+ return false;
+ }
+
+ if (!IsValidMessageHeader(message->header()))
+ return false;
+
+ return sink_->Accept(message);
+}
+
+} // namespace internal
+} // namespace mojo
diff --git a/chromium/mojo/public/cpp/bindings/lib/message_header_validator.h b/chromium/mojo/public/cpp/bindings/lib/message_header_validator.h
new file mode 100644
index 00000000000..c3f43a07fbc
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/message_header_validator.h
@@ -0,0 +1,24 @@
+// 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.
+
+#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_MESSAGE_HEADER_VALIDATOR_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_LIB_MESSAGE_HEADER_VALIDATOR_H_
+
+#include "mojo/public/cpp/bindings/message.h"
+#include "mojo/public/cpp/bindings/message_filter.h"
+
+namespace mojo {
+namespace internal {
+
+class MessageHeaderValidator : public MessageFilter {
+ public:
+ explicit MessageHeaderValidator(MessageReceiver* sink = NULL);
+
+ virtual bool Accept(Message* message) MOJO_OVERRIDE;
+};
+
+} // namespace internal
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_MESSAGE_HEADER_VALIDATOR_H_
diff --git a/chromium/mojo/public/cpp/bindings/lib/message_internal.h b/chromium/mojo/public/cpp/bindings/lib/message_internal.h
new file mode 100644
index 00000000000..3c67902b7a8
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/message_internal.h
@@ -0,0 +1,44 @@
+// 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.
+
+#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_MESSAGE_INTERNAL_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_LIB_MESSAGE_INTERNAL_H_
+
+#include "mojo/public/cpp/bindings/lib/bindings_internal.h"
+
+namespace mojo {
+namespace internal {
+
+#pragma pack(push, 1)
+
+enum {
+ kMessageExpectsResponse = 1 << 0,
+ kMessageIsResponse = 1 << 1
+};
+
+struct MessageHeader : internal::StructHeader {
+ uint32_t name;
+ uint32_t flags;
+};
+MOJO_COMPILE_ASSERT(sizeof(MessageHeader) == 16, bad_sizeof_MessageHeader);
+
+struct MessageHeaderWithRequestID : MessageHeader {
+ uint64_t request_id;
+};
+MOJO_COMPILE_ASSERT(sizeof(MessageHeaderWithRequestID) == 24,
+ bad_sizeof_MessageHeaderWithRequestID);
+
+struct MessageData {
+ MessageHeader header;
+};
+
+MOJO_COMPILE_ASSERT(sizeof(MessageData) == sizeof(MessageHeader),
+ bad_sizeof_MessageData);
+
+#pragma pack(pop)
+
+} // namespace internal
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_MESSAGE_INTERNAL_H_
diff --git a/chromium/mojo/public/cpp/bindings/lib/message_queue.cc b/chromium/mojo/public/cpp/bindings/lib/message_queue.cc
new file mode 100644
index 00000000000..1982ccb14c2
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/message_queue.cc
@@ -0,0 +1,50 @@
+// Copyright 2013 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/public/cpp/bindings/lib/message_queue.h"
+
+#include <assert.h>
+#include <stddef.h>
+
+#include "mojo/public/cpp/bindings/message.h"
+
+namespace mojo {
+namespace internal {
+
+MessageQueue::MessageQueue() {
+}
+
+MessageQueue::~MessageQueue() {
+ while (!queue_.empty())
+ Pop();
+}
+
+bool MessageQueue::IsEmpty() const {
+ return queue_.empty();
+}
+
+Message* MessageQueue::Peek() {
+ assert(!queue_.empty());
+ return queue_.front();
+}
+
+void MessageQueue::Push(Message* message) {
+ queue_.push(new Message());
+ queue_.back()->Swap(message);
+}
+
+void MessageQueue::Pop(Message* message) {
+ assert(!queue_.empty());
+ queue_.front()->Swap(message);
+ Pop();
+}
+
+void MessageQueue::Pop() {
+ assert(!queue_.empty());
+ delete queue_.front();
+ queue_.pop();
+}
+
+} // namespace internal
+} // namespace mojo
diff --git a/chromium/mojo/public/cpp/bindings/lib/message_queue.h b/chromium/mojo/public/cpp/bindings/lib/message_queue.h
new file mode 100644
index 00000000000..4e46b54a250
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/message_queue.h
@@ -0,0 +1,47 @@
+// Copyright 2013 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.
+
+#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_MESSAGE_QUEUE_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_LIB_MESSAGE_QUEUE_H_
+
+#include <queue>
+
+#include "mojo/public/cpp/system/macros.h"
+
+namespace mojo {
+class Message;
+
+namespace internal {
+
+// A queue for Message objects.
+class MessageQueue {
+ public:
+ MessageQueue();
+ ~MessageQueue();
+
+ bool IsEmpty() const;
+ Message* Peek();
+
+ // This method transfers ownership of |message->data| and |message->handles|
+ // to the message queue, resetting |message| in the process.
+ void Push(Message* message);
+
+ // Removes the next message from the queue, transferring ownership of its
+ // data and handles to the given |message|.
+ void Pop(Message* message);
+
+ // Removes the next message from the queue, discarding its data and handles.
+ // This is meant to be used in conjunction with |Peek|.
+ void Pop();
+
+ private:
+ std::queue<Message*> queue_;
+
+ MOJO_DISALLOW_COPY_AND_ASSIGN(MessageQueue);
+};
+
+} // namespace internal
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_MESSAGE_QUEUE_H_
diff --git a/chromium/mojo/public/cpp/bindings/lib/no_interface.cc b/chromium/mojo/public/cpp/bindings/lib/no_interface.cc
new file mode 100644
index 00000000000..9e0945c83b3
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/no_interface.cc
@@ -0,0 +1,20 @@
+// 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/public/cpp/bindings/no_interface.h"
+
+namespace mojo {
+
+const char* NoInterface::Name_ = "mojo::NoInterface";
+
+bool NoInterfaceStub::Accept(Message* message) {
+ return false;
+}
+
+bool NoInterfaceStub::AcceptWithResponder(Message* message,
+ MessageReceiver* responder) {
+ return false;
+}
+
+} // namespace mojo
diff --git a/chromium/mojo/public/cpp/bindings/lib/router.cc b/chromium/mojo/public/cpp/bindings/lib/router.cc
new file mode 100644
index 00000000000..a8222203c47
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/router.cc
@@ -0,0 +1,140 @@
+// 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/public/cpp/bindings/lib/router.h"
+
+namespace mojo {
+namespace internal {
+
+// ----------------------------------------------------------------------------
+
+class ResponderThunk : public MessageReceiver {
+ public:
+ explicit ResponderThunk(const SharedData<Router*>& router)
+ : router_(router) {
+ }
+ virtual ~ResponderThunk() {
+ }
+
+ // MessageReceiver implementation:
+ virtual bool Accept(Message* message) MOJO_OVERRIDE {
+ assert(message->has_flag(kMessageIsResponse));
+
+ bool result = false;
+
+ Router* router = router_.value();
+ if (router)
+ result = router->Accept(message);
+
+ return result;
+ }
+
+ private:
+ SharedData<Router*> router_;
+};
+
+// ----------------------------------------------------------------------------
+
+Router::HandleIncomingMessageThunk::HandleIncomingMessageThunk(Router* router)
+ : router_(router) {
+}
+
+Router::HandleIncomingMessageThunk::~HandleIncomingMessageThunk() {
+}
+
+bool Router::HandleIncomingMessageThunk::Accept(Message* message) {
+ return router_->HandleIncomingMessage(message);
+}
+
+// ----------------------------------------------------------------------------
+
+Router::Router(ScopedMessagePipeHandle message_pipe,
+ FilterChain filters,
+ const MojoAsyncWaiter* waiter)
+ : thunk_(this),
+ filters_(filters.Pass()),
+ connector_(message_pipe.Pass(), waiter),
+ weak_self_(this),
+ incoming_receiver_(NULL),
+ next_request_id_(0),
+ testing_mode_(false) {
+ filters_.SetSink(&thunk_);
+ connector_.set_incoming_receiver(filters_.GetHead());
+}
+
+Router::~Router() {
+ weak_self_.set_value(NULL);
+
+ for (ResponderMap::const_iterator i = responders_.begin();
+ i != responders_.end(); ++i) {
+ delete i->second;
+ }
+}
+
+bool Router::Accept(Message* message) {
+ assert(!message->has_flag(kMessageExpectsResponse));
+ return connector_.Accept(message);
+}
+
+bool Router::AcceptWithResponder(Message* message,
+ MessageReceiver* responder) {
+ assert(message->has_flag(kMessageExpectsResponse));
+
+ // Reserve 0 in case we want it to convey special meaning in the future.
+ uint64_t request_id = next_request_id_++;
+ if (request_id == 0)
+ request_id = next_request_id_++;
+
+ message->set_request_id(request_id);
+ if (!connector_.Accept(message))
+ return false;
+
+ // We assume ownership of |responder|.
+ responders_[request_id] = responder;
+ return true;
+}
+
+void Router::EnableTestingMode() {
+ testing_mode_ = true;
+ connector_.set_enforce_errors_from_incoming_receiver(false);
+}
+
+bool Router::HandleIncomingMessage(Message* message) {
+ if (message->has_flag(kMessageExpectsResponse)) {
+ if (incoming_receiver_) {
+ MessageReceiver* responder = new ResponderThunk(weak_self_);
+ bool ok = incoming_receiver_->AcceptWithResponder(message, responder);
+ if (!ok)
+ delete responder;
+ return ok;
+ }
+
+ // If we receive a request expecting a response when the client is not
+ // listening, then we have no choice but to tear down the pipe.
+ connector_.CloseMessagePipe();
+ } else if (message->has_flag(kMessageIsResponse)) {
+ uint64_t request_id = message->request_id();
+ ResponderMap::iterator it = responders_.find(request_id);
+ if (it == responders_.end()) {
+ assert(testing_mode_);
+ return false;
+ }
+ MessageReceiver* responder = it->second;
+ responders_.erase(it);
+ bool ok = responder->Accept(message);
+ delete responder;
+ return ok;
+ } else {
+ if (incoming_receiver_)
+ return incoming_receiver_->Accept(message);
+ // OK to drop message on the floor.
+ }
+
+ return false;
+}
+
+// ----------------------------------------------------------------------------
+
+} // namespace internal
+} // namespace mojo
diff --git a/chromium/mojo/public/cpp/bindings/lib/router.h b/chromium/mojo/public/cpp/bindings/lib/router.h
new file mode 100644
index 00000000000..76bf1471e2e
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/router.h
@@ -0,0 +1,91 @@
+// 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.
+
+#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_ROUTER_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_LIB_ROUTER_H_
+
+#include <map>
+
+#include "mojo/public/cpp/bindings/lib/connector.h"
+#include "mojo/public/cpp/bindings/lib/filter_chain.h"
+#include "mojo/public/cpp/bindings/lib/shared_data.h"
+#include "mojo/public/cpp/environment/environment.h"
+
+namespace mojo {
+namespace internal {
+
+class Router : public MessageReceiverWithResponder {
+ public:
+ Router(ScopedMessagePipeHandle message_pipe,
+ FilterChain filters,
+ const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter());
+ virtual ~Router();
+
+ // Sets the receiver to handle messages read from the message pipe that do
+ // not have the kMessageIsResponse flag set.
+ void set_incoming_receiver(MessageReceiverWithResponder* receiver) {
+ incoming_receiver_ = receiver;
+ }
+
+ // Sets the error handler to receive notifications when an error is
+ // encountered while reading from the pipe or waiting to read from the pipe.
+ void set_error_handler(ErrorHandler* error_handler) {
+ connector_.set_error_handler(error_handler);
+ }
+
+ // Returns true if an error was encountered while reading from the pipe or
+ // waiting to read from the pipe.
+ bool encountered_error() const { return connector_.encountered_error(); }
+
+ void CloseMessagePipe() {
+ connector_.CloseMessagePipe();
+ }
+
+ ScopedMessagePipeHandle PassMessagePipe() {
+ return connector_.PassMessagePipe();
+ }
+
+ // MessageReceiver implementation:
+ virtual bool Accept(Message* message) MOJO_OVERRIDE;
+ virtual bool AcceptWithResponder(Message* message, MessageReceiver* responder)
+ MOJO_OVERRIDE;
+
+ // Sets this object to testing mode.
+ // In testing mode:
+ // - the object is more tolerant of unrecognized response messages;
+ // - the connector continues working after seeing errors from its incoming
+ // receiver.
+ void EnableTestingMode();
+
+ private:
+ typedef std::map<uint64_t, MessageReceiver*> ResponderMap;
+
+ class HandleIncomingMessageThunk : public MessageReceiver {
+ public:
+ HandleIncomingMessageThunk(Router* router);
+ virtual ~HandleIncomingMessageThunk();
+
+ // MessageReceiver implementation:
+ virtual bool Accept(Message* message) MOJO_OVERRIDE;
+
+ private:
+ Router* router_;
+ };
+
+ bool HandleIncomingMessage(Message* message);
+
+ HandleIncomingMessageThunk thunk_;
+ FilterChain filters_;
+ Connector connector_;
+ SharedData<Router*> weak_self_;
+ MessageReceiverWithResponder* incoming_receiver_;
+ ResponderMap responders_;
+ uint64_t next_request_id_;
+ bool testing_mode_;
+};
+
+} // namespace internal
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_ROUTER_H_
diff --git a/chromium/mojo/public/cpp/bindings/lib/shared_data.h b/chromium/mojo/public/cpp/bindings/lib/shared_data.h
new file mode 100644
index 00000000000..c7bd54f8d7c
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/shared_data.h
@@ -0,0 +1,84 @@
+// 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.
+
+#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_SHARED_DATA_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_LIB_SHARED_DATA_H_
+
+#include "mojo/public/cpp/system/macros.h"
+
+namespace mojo {
+namespace internal {
+
+// Used to allocate an instance of T that can be shared via reference counting.
+template <typename T>
+class SharedData {
+ public:
+ ~SharedData() {
+ holder_->Release();
+ }
+
+ SharedData() : holder_(new Holder()) {
+ }
+
+ explicit SharedData(const T& value) : holder_(new Holder(value)) {
+ }
+
+ SharedData(const SharedData<T>& other) : holder_(other.holder_) {
+ holder_->Retain();
+ }
+
+ SharedData<T>& operator=(const SharedData<T>& other) {
+ if (other.holder_ == holder_)
+ return *this;
+ holder_->Release();
+ holder_ = other.holder_;
+ holder_->Retain();
+ return *this;
+ }
+
+ void reset() {
+ holder_->Release();
+ holder_ = new Holder();
+ }
+
+ void reset(const T& value) {
+ holder_->Release();
+ holder_ = new Holder(value);
+ }
+
+ void set_value(const T& value) {
+ holder_->value = value;
+ }
+ T* mutable_value() {
+ return &holder_->value;
+ }
+ const T& value() const {
+ return holder_->value;
+ }
+
+ private:
+ class Holder {
+ public:
+ Holder() : value(), ref_count_(1) {
+ }
+ Holder(const T& value) : value(value), ref_count_(1) {
+ }
+
+ void Retain() { ++ref_count_; }
+ void Release() { if (--ref_count_ == 0) delete this; }
+
+ T value;
+
+ private:
+ int ref_count_;
+ MOJO_DISALLOW_COPY_AND_ASSIGN(Holder);
+ };
+
+ Holder* holder_;
+};
+
+} // namespace internal
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_SHARED_DATA_H_
diff --git a/chromium/mojo/public/cpp/bindings/lib/shared_ptr.h b/chromium/mojo/public/cpp/bindings/lib/shared_ptr.h
new file mode 100644
index 00000000000..6ae53a5681a
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/shared_ptr.h
@@ -0,0 +1,63 @@
+// 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.
+
+#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_SHARED_PTR_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_LIB_SHARED_PTR_H_
+
+#include "mojo/public/cpp/bindings/lib/shared_data.h"
+
+namespace mojo {
+namespace internal {
+
+// Used to manage a heap-allocated instance of P that can be shared via
+// reference counting. When the last reference is dropped, the instance is
+// deleted.
+template <typename P>
+class SharedPtr {
+ public:
+ SharedPtr() {}
+
+ explicit SharedPtr(P* ptr) {
+ impl_.mutable_value()->ptr = ptr;
+ }
+
+ // Default copy-constructor and assignment operator are OK.
+
+ P* get() {
+ return impl_.value().ptr;
+ }
+ const P* get() const {
+ return impl_.value().ptr;
+ }
+
+ P* operator->() { return get(); }
+ const P* operator->() const { return get(); }
+
+ private:
+ class Impl {
+ public:
+ ~Impl() {
+ if (ptr)
+ delete ptr;
+ }
+
+ Impl() : ptr(NULL) {
+ }
+
+ Impl(P* ptr) : ptr(ptr) {
+ }
+
+ P* ptr;
+
+ private:
+ MOJO_DISALLOW_COPY_AND_ASSIGN(Impl);
+ };
+
+ SharedData<Impl> impl_;
+};
+
+} // namespace mojo
+} // namespace internal
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_SHARED_PTR_H_
diff --git a/chromium/mojo/public/cpp/bindings/lib/string_serialization.cc b/chromium/mojo/public/cpp/bindings/lib/string_serialization.cc
new file mode 100644
index 00000000000..0044b1b9cff
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/string_serialization.cc
@@ -0,0 +1,38 @@
+// 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/public/cpp/bindings/lib/string_serialization.h"
+
+#include <string.h>
+
+namespace mojo {
+
+size_t GetSerializedSize_(const String& input) {
+ if (!input)
+ return 0;
+ return internal::Align(sizeof(internal::String_Data) + input.size());
+}
+
+void Serialize_(const String& input, internal::Buffer* buf,
+ internal::String_Data** output) {
+ if (input) {
+ internal::String_Data* result =
+ internal::String_Data::New(input.size(), buf);
+ memcpy(result->storage(), input.data(), input.size());
+ *output = result;
+ } else {
+ *output = NULL;
+ }
+}
+
+void Deserialize_(internal::String_Data* input, String* output) {
+ if (input) {
+ String result(input->storage(), input->size());
+ result.Swap(output);
+ } else {
+ output->reset();
+ }
+}
+
+} // namespace mojo
diff --git a/chromium/mojo/public/cpp/bindings/lib/string_serialization.h b/chromium/mojo/public/cpp/bindings/lib/string_serialization.h
new file mode 100644
index 00000000000..bad2a0c2766
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/string_serialization.h
@@ -0,0 +1,20 @@
+// 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.
+
+#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_STRING_SERIALIZATION_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_LIB_STRING_SERIALIZATION_H_
+
+#include "mojo/public/cpp/bindings/lib/array_internal.h"
+#include "mojo/public/cpp/bindings/string.h"
+
+namespace mojo {
+
+size_t GetSerializedSize_(const String& input);
+void Serialize_(const String& input, internal::Buffer* buffer,
+ internal::String_Data** output);
+void Deserialize_(internal::String_Data* input, String* output);
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_STRING_SERIALIZATION_H_
diff --git a/chromium/mojo/public/cpp/bindings/lib/sync_dispatcher.cc b/chromium/mojo/public/cpp/bindings/lib/sync_dispatcher.cc
new file mode 100644
index 00000000000..2cde97f6ee4
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/sync_dispatcher.cc
@@ -0,0 +1,27 @@
+// 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/public/cpp/bindings/sync_dispatcher.h"
+
+#include <stdlib.h>
+
+#include "mojo/public/cpp/bindings/message.h"
+
+namespace mojo {
+
+bool WaitForMessageAndDispatch(MessagePipeHandle handle,
+ MessageReceiver* receiver) {
+ while (true) {
+ bool result;
+ MojoResult rv = ReadAndDispatchMessage(handle, receiver, &result);
+ if (rv == MOJO_RESULT_OK)
+ return result;
+ if (rv == MOJO_RESULT_SHOULD_WAIT)
+ rv = Wait(handle, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE);
+ if (rv != MOJO_RESULT_OK)
+ return false;
+ }
+}
+
+} // namespace mojo
diff --git a/chromium/mojo/public/cpp/bindings/lib/template_util.h b/chromium/mojo/public/cpp/bindings/lib/template_util.h
new file mode 100644
index 00000000000..599126691ed
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/template_util.h
@@ -0,0 +1,89 @@
+// 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.
+
+#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_TEMPLATE_UTIL_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_LIB_TEMPLATE_UTIL_H_
+
+namespace mojo {
+namespace internal {
+
+template<class T, T v>
+struct IntegralConstant {
+ static const T value = v;
+};
+
+template <class T, T v> const T IntegralConstant<T, v>::value;
+
+typedef IntegralConstant<bool, true> TrueType;
+typedef IntegralConstant<bool, false> FalseType;
+
+template <class T> struct IsConst : FalseType {};
+template <class T> struct IsConst<const T> : TrueType {};
+
+template<bool B, typename T = void>
+struct EnableIf {};
+
+template<typename T>
+struct EnableIf<true, T> { typedef T type; };
+
+// Types YesType and NoType are guaranteed such that sizeof(YesType) <
+// sizeof(NoType).
+typedef char YesType;
+
+struct NoType {
+ YesType dummy[2];
+};
+
+// A helper template to determine if given type is non-const move-only-type,
+// i.e. if a value of the given type should be passed via .Pass() in a
+// destructive way.
+template <typename T> struct IsMoveOnlyType {
+ template <typename U>
+ static YesType Test(const typename U::MoveOnlyTypeForCPP03*);
+
+ template <typename U>
+ static NoType Test(...);
+
+ static const bool value = sizeof(Test<T>(0)) == sizeof(YesType) &&
+ !IsConst<T>::value;
+};
+
+template <typename T>
+typename EnableIf<!IsMoveOnlyType<T>::value, T>::type& Forward(T& t) {
+ return t;
+}
+
+template <typename T>
+typename EnableIf<IsMoveOnlyType<T>::value, T>::type Forward(T& t) {
+ return t.Pass();
+}
+
+// This goop is a trick used to implement a template that can be used to
+// determine if a given class is the base class of another given class.
+template<typename, typename> struct IsSame {
+ static bool const value = false;
+};
+template<typename A> struct IsSame<A, A> {
+ static bool const value = true;
+};
+template<typename Base, typename Derived> struct IsBaseOf {
+ private:
+ // This class doesn't work correctly with forward declarations.
+ // Because sizeof cannot be applied to incomplete types, this line prevents us
+ // from passing in forward declarations.
+ typedef char (*EnsureTypesAreComplete)[sizeof(Base) + sizeof(Derived)];
+
+ static Derived* CreateDerived();
+ static char (&Check(Base*))[1];
+ static char (&Check(...))[2];
+
+ public:
+ static bool const value = sizeof Check(CreateDerived()) == 1 &&
+ !IsSame<Base const, void const>::value;
+};
+
+} // namespace internal
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_TEMPLATE_UTIL_H_
diff --git a/chromium/mojo/public/cpp/bindings/lib/validation_errors.cc b/chromium/mojo/public/cpp/bindings/lib/validation_errors.cc
new file mode 100644
index 00000000000..ed5904d3963
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/validation_errors.cc
@@ -0,0 +1,64 @@
+// 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/public/cpp/bindings/lib/validation_errors.h"
+
+#include <assert.h>
+#include <stdio.h>
+
+namespace mojo {
+namespace internal {
+namespace {
+
+ValidationErrorObserverForTesting* g_validation_error_observer = NULL;
+
+} // namespace
+
+const char* ValidationErrorToString(ValidationError error) {
+ switch (error) {
+ case VALIDATION_ERROR_NONE:
+ return "VALIDATION_ERROR_NONE";
+ case VALIDATION_ERROR_MISALIGNED_OBJECT:
+ return "VALIDATION_ERROR_MISALIGNED_OBJECT";
+ case VALIDATION_ERROR_ILLEGAL_MEMORY_RANGE:
+ return "VALIDATION_ERROR_ILLEGAL_MEMORY_RANGE";
+ case VALIDATION_ERROR_UNEXPECTED_STRUCT_HEADER:
+ return "VALIDATION_ERROR_UNEXPECTED_STRUCT_HEADER";
+ case VALIDATION_ERROR_UNEXPECTED_ARRAY_HEADER:
+ return "VALIDATION_ERROR_UNEXPECTED_ARRAY_HEADER";
+ case VALIDATION_ERROR_ILLEGAL_HANDLE:
+ return "VALIDATION_ERROR_ILLEGAL_HANDLE";
+ case VALIDATION_ERROR_ILLEGAL_POINTER:
+ return "VALIDATION_ERROR_ILLEGAL_POINTER";
+ case VALIDATION_ERROR_MESSAGE_HEADER_INVALID_FLAG_COMBINATION:
+ return "VALIDATION_ERROR_MESSAGE_HEADER_INVALID_FLAG_COMBINATION";
+ case VALIDATION_ERROR_MESSAGE_HEADER_MISSING_REQUEST_ID:
+ return "VALIDATION_ERROR_MESSAGE_HEADER_MISSING_REQUEST_ID";
+ }
+
+ return "Unknown error";
+}
+
+void ReportValidationError(ValidationError error) {
+ if (g_validation_error_observer) {
+ g_validation_error_observer->set_last_error(error);
+ } else {
+ // TODO(yzshen): Consider adding better logging support.
+ fprintf(stderr, "Invalid message: %s\n", ValidationErrorToString(error));
+ }
+}
+
+ValidationErrorObserverForTesting::ValidationErrorObserverForTesting()
+ : last_error_(VALIDATION_ERROR_NONE) {
+ assert(!g_validation_error_observer);
+ g_validation_error_observer = this;
+}
+
+ValidationErrorObserverForTesting::~ValidationErrorObserverForTesting() {
+ assert(g_validation_error_observer == this);
+ g_validation_error_observer = NULL;
+}
+
+} // namespace internal
+} // namespace mojo
diff --git a/chromium/mojo/public/cpp/bindings/lib/validation_errors.h b/chromium/mojo/public/cpp/bindings/lib/validation_errors.h
new file mode 100644
index 00000000000..9b443c371e5
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/validation_errors.h
@@ -0,0 +1,66 @@
+// 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.
+
+#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_VALIDATION_ERRORS_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_LIB_VALIDATION_ERRORS_H_
+
+#include "mojo/public/cpp/system/macros.h"
+
+namespace mojo {
+namespace internal {
+
+enum ValidationError {
+ // There is no validation error.
+ VALIDATION_ERROR_NONE,
+ // An object (struct or array) is not 8-byte aligned.
+ VALIDATION_ERROR_MISALIGNED_OBJECT,
+ // An object is not contained inside the message data, or it overlaps other
+ // objects.
+ VALIDATION_ERROR_ILLEGAL_MEMORY_RANGE,
+ // A struct header doesn't make sense, for example:
+ // - |num_bytes| is smaller than the size of the oldest version that we
+ // support.
+ // - |num_fields| is smaller than the field number of the oldest version that
+ // we support.
+ // - |num_bytes| and |num_fields| don't match.
+ VALIDATION_ERROR_UNEXPECTED_STRUCT_HEADER,
+ // An array header doesn't make sense, for example:
+ // - |num_bytes| is smaller than the size of the header plus the size required
+ // to store |num_elements| elements.
+ VALIDATION_ERROR_UNEXPECTED_ARRAY_HEADER,
+ // An encoded handle is illegal.
+ VALIDATION_ERROR_ILLEGAL_HANDLE,
+ // An encoded pointer is illegal.
+ VALIDATION_ERROR_ILLEGAL_POINTER,
+ // |flags| in the message header is an invalid flag combination.
+ VALIDATION_ERROR_MESSAGE_HEADER_INVALID_FLAG_COMBINATION,
+ // |flags| in the message header indicates that a request ID is required but
+ // there isn't one.
+ VALIDATION_ERROR_MESSAGE_HEADER_MISSING_REQUEST_ID,
+};
+
+const char* ValidationErrorToString(ValidationError error);
+
+void ReportValidationError(ValidationError error);
+
+// Only used by validation tests and when there is only one thread doing message
+// validation.
+class ValidationErrorObserverForTesting {
+ public:
+ ValidationErrorObserverForTesting();
+ ~ValidationErrorObserverForTesting();
+
+ ValidationError last_error() const { return last_error_; }
+ void set_last_error(ValidationError error) { last_error_ = error; }
+
+ private:
+ ValidationError last_error_;
+
+ MOJO_DISALLOW_COPY_AND_ASSIGN(ValidationErrorObserverForTesting);
+};
+
+} // namespace internal
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_VALIDATION_ERRORS_H_
diff --git a/chromium/mojo/public/cpp/bindings/message.h b/chromium/mojo/public/cpp/bindings/message.h
new file mode 100644
index 00000000000..beb1cd9036f
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/message.h
@@ -0,0 +1,123 @@
+// 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.
+
+#ifndef MOJO_PUBLIC_CPP_BINDINGS_MESSAGE_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_MESSAGE_H_
+
+#include <assert.h>
+
+#include <vector>
+
+#include "mojo/public/cpp/bindings/lib/message_internal.h"
+
+namespace mojo {
+
+// Message is a holder for the data and handles to be sent over a MessagePipe.
+// Message owns its data and handles, but a consumer of Message is free to
+// mutate the data and handles. The message's data is comprised of a header
+// followed by payload.
+class Message {
+ public:
+ Message();
+ ~Message();
+
+ // These may only be called on a newly created Message object.
+ void AllocUninitializedData(uint32_t num_bytes);
+ void AdoptData(uint32_t num_bytes, internal::MessageData* data);
+
+ // Swaps data and handles between this Message and another.
+ void Swap(Message* other);
+
+ uint32_t data_num_bytes() const { return data_num_bytes_; }
+
+ // Access the raw bytes of the message.
+ const uint8_t* data() const { return
+ reinterpret_cast<const uint8_t*>(data_);
+ }
+ uint8_t* mutable_data() { return reinterpret_cast<uint8_t*>(data_); }
+
+ // Access the header.
+ const internal::MessageHeader* header() const { return &data_->header; }
+
+ uint32_t name() const { return data_->header.name; }
+ bool has_flag(uint32_t flag) const { return !!(data_->header.flags & flag); }
+
+ // Access the request_id field (if present).
+ bool has_request_id() const { return data_->header.num_fields >= 3; }
+ uint64_t request_id() const {
+ assert(has_request_id());
+ return static_cast<const internal::MessageHeaderWithRequestID*>(
+ &data_->header)->request_id;
+ }
+ void set_request_id(uint64_t request_id) {
+ assert(has_request_id());
+ static_cast<internal::MessageHeaderWithRequestID*>(&data_->header)->
+ request_id = request_id;
+ }
+
+ // Access the payload.
+ const uint8_t* payload() const {
+ return reinterpret_cast<const uint8_t*>(data_) + data_->header.num_bytes;
+ }
+ uint8_t* mutable_payload() {
+ return reinterpret_cast<uint8_t*>(data_) + data_->header.num_bytes;
+ }
+ uint32_t payload_num_bytes() const {
+ assert(data_num_bytes_ >= data_->header.num_bytes);
+ return data_num_bytes_ - data_->header.num_bytes;
+ }
+
+ // Access the handles.
+ const std::vector<Handle>* handles() const { return &handles_; }
+ std::vector<Handle>* mutable_handles() { return &handles_; }
+
+ private:
+ uint32_t data_num_bytes_;
+ internal::MessageData* data_; // Heap-allocated using malloc.
+ std::vector<Handle> handles_;
+
+ MOJO_DISALLOW_COPY_AND_ASSIGN(Message);
+};
+
+class MessageReceiver {
+ public:
+ virtual ~MessageReceiver() {}
+
+ // The receiver may mutate the given message. Returns true if the message
+ // was accepted and false otherwise, indicating that the message was invalid
+ // or malformed.
+ virtual bool Accept(Message* message) MOJO_WARN_UNUSED_RESULT = 0;
+};
+
+class MessageReceiverWithResponder : public MessageReceiver {
+ public:
+ virtual ~MessageReceiverWithResponder() {}
+
+ // A variant on Accept that registers a MessageReceiver (known as the
+ // responder) to handle the response message generated from the given
+ // message. The responder's Accept method may be called during
+ // AcceptWithResponder or some time after its return.
+ //
+ // NOTE: Upon returning true, AcceptWithResponder assumes ownership of
+ // |responder| and will delete it after calling |responder->Accept| or upon
+ // its own destruction.
+ //
+ virtual bool AcceptWithResponder(
+ Message* message, MessageReceiver* responder) MOJO_WARN_UNUSED_RESULT = 0;
+};
+
+// Read a single message from the pipe and dispatch to the given receiver. The
+// receiver may be null, in which case the message is simply discarded.
+// Returns MOJO_RESULT_SHOULD_WAIT if the caller should wait on the handle to
+// become readable. Returns MOJO_RESULT_OK if a message was dispatched and
+// otherwise returns an error code if something went wrong.
+//
+// NOTE: The message hasn't been validated and may be malformed!
+MojoResult ReadAndDispatchMessage(MessagePipeHandle handle,
+ MessageReceiver* receiver,
+ bool* receiver_result);
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_MESSAGE_H_
diff --git a/chromium/mojo/public/cpp/bindings/message_filter.h b/chromium/mojo/public/cpp/bindings/message_filter.h
new file mode 100644
index 00000000000..6d716733ecc
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/message_filter.h
@@ -0,0 +1,39 @@
+// 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.
+
+#ifndef MOJO_PUBLIC_CPP_BINDINGS_MESSAGE_FILTER_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_MESSAGE_FILTER_H_
+
+#include "mojo/public/cpp/bindings/message.h"
+#include "mojo/public/cpp/system/macros.h"
+
+namespace mojo {
+
+// This class is the base class for message filters. Subclasses should
+// implement the pure virtual method Accept() inherited from MessageReceiver to
+// process messages and/or forward them to |sink_|.
+class MessageFilter : public MessageReceiver {
+ public:
+ // Doesn't take ownership of |sink|. Therefore |sink| has to stay alive while
+ // this object is alive.
+ explicit MessageFilter(MessageReceiver* sink = NULL);
+ virtual ~MessageFilter();
+
+ void set_sink(MessageReceiver* sink) { sink_ = sink; }
+
+ protected:
+ MessageReceiver* sink_;
+};
+
+// A trivial filter that simply forwards every message it receives to |sink_|.
+class PassThroughFilter : public MessageFilter {
+ public:
+ explicit PassThroughFilter(MessageReceiver* sink = NULL);
+
+ virtual bool Accept(Message* message) MOJO_OVERRIDE;
+};
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_MESSAGE_FILTER_H_
diff --git a/chromium/mojo/public/cpp/bindings/no_interface.h b/chromium/mojo/public/cpp/bindings/no_interface.h
new file mode 100644
index 00000000000..83b0eff5000
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/no_interface.h
@@ -0,0 +1,56 @@
+// 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.
+
+#ifndef MOJO_PUBLIC_CPP_BINDINGS_NO_INTERFACE_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_NO_INTERFACE_H_
+
+#include <assert.h>
+
+#include "mojo/public/cpp/bindings/message.h"
+#include "mojo/public/cpp/bindings/message_filter.h"
+#include "mojo/public/cpp/system/core.h"
+
+namespace mojo {
+
+// NoInterface is for use in cases when a non-existent or empty interface is
+// needed (e.g., when the Mojom "Peer" attribute is not present).
+
+class NoInterfaceProxy;
+class NoInterfaceStub;
+
+class NoInterface {
+ public:
+ static const char* Name_;
+ typedef NoInterfaceProxy Proxy_;
+ typedef NoInterfaceStub Stub_;
+ typedef PassThroughFilter RequestValidator_;
+ typedef PassThroughFilter ResponseValidator_;
+ typedef NoInterface Client;
+ virtual ~NoInterface() {}
+};
+
+class NoInterfaceProxy : public NoInterface {
+ public:
+ explicit NoInterfaceProxy(MessageReceiver* receiver) {}
+};
+
+class NoInterfaceStub : public MessageReceiverWithResponder {
+ public:
+ NoInterfaceStub() {}
+ void set_sink(NoInterface* sink) {}
+ NoInterface* sink() { return NULL; }
+ virtual bool Accept(Message* message) MOJO_OVERRIDE;
+ virtual bool AcceptWithResponder(Message* message, MessageReceiver* responder)
+ MOJO_OVERRIDE;
+};
+
+
+// AnyInterface is for use in cases where any interface would do (e.g., see the
+// Shell::Connect method).
+
+typedef NoInterface AnyInterface;
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_NO_INTERFACE_H_
diff --git a/chromium/mojo/public/cpp/bindings/string.h b/chromium/mojo/public/cpp/bindings/string.h
new file mode 100644
index 00000000000..a2427844975
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/string.h
@@ -0,0 +1,154 @@
+// 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.
+
+#ifndef MOJO_PUBLIC_CPP_BINDINGS_STRING_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_STRING_H_
+
+#include <assert.h>
+
+#include <string>
+
+#include "mojo/public/cpp/bindings/lib/array_internal.h"
+#include "mojo/public/cpp/bindings/type_converter.h"
+#include "mojo/public/cpp/system/macros.h"
+
+namespace mojo {
+
+class String {
+ public:
+ typedef internal::String_Data Data_;
+
+ String() : is_null_(true) {}
+ String(const std::string& str) : value_(str), is_null_(false) {}
+ String(const char* chars) : is_null_(!chars) {
+ if (chars)
+ value_ = chars;
+ }
+ String(const char* chars, size_t num_chars)
+ : value_(chars, num_chars),
+ is_null_(false) {
+ }
+ template <size_t N>
+ String(const char chars[N]) : value_(chars, N-1), is_null_(false) {}
+
+ template <typename U>
+ static String From(const U& other) {
+ return TypeConverter<String, U>::ConvertFrom(other);
+ }
+
+ template <typename U>
+ U To() const {
+ return TypeConverter<String, U>::ConvertTo(*this);
+ }
+
+ String& operator=(const std::string& str) {
+ value_ = str;
+ is_null_ = false;
+ return *this;
+ }
+ String& operator=(const char* chars) {
+ is_null_ = !chars;
+ if (chars) {
+ value_ = chars;
+ } else {
+ value_.clear();
+ }
+ return *this;
+ }
+
+ void reset() {
+ value_.clear();
+ is_null_ = true;
+ }
+
+ bool is_null() const { return is_null_; }
+
+ size_t size() const { return value_.size(); }
+
+ const char* data() const { return value_.data(); }
+
+ const char& at(size_t offset) const { return value_.at(offset); }
+ const char& operator[](size_t offset) const { return value_[offset]; }
+
+ const std::string& get() const { return value_; }
+ operator const std::string&() const { return value_; }
+
+ void Swap(String* other) {
+ std::swap(is_null_, other->is_null_);
+ value_.swap(other->value_);
+ }
+
+ void Swap(std::string* other) {
+ is_null_ = false;
+ value_.swap(*other);
+ }
+
+ private:
+ typedef std::string String::*Testable;
+
+ public:
+ operator Testable() const { return is_null_ ? 0 : &String::value_; }
+
+ private:
+ std::string value_;
+ bool is_null_;
+};
+
+inline bool operator==(const String& a, const String& b) {
+ return a.is_null() == b.is_null() && a.get() == b.get();
+}
+inline bool operator==(const char* a, const String& b) {
+ return !b.is_null() && a == b.get();
+}
+inline bool operator==(const String& a, const char* b) {
+ return !a.is_null() && a.get() == b;
+}
+inline bool operator!=(const String& a, const String& b) { return !(a == b); }
+inline bool operator!=(const char* a, const String& b) { return !(a == b); }
+inline bool operator!=(const String& a, const char* b) { return !(a == b); }
+
+// TODO(darin): Add similar variants of operator<,<=,>,>=
+
+template <>
+class TypeConverter<String, std::string> {
+ public:
+ static String ConvertFrom(const std::string& input) {
+ return String(input);
+ }
+ static std::string ConvertTo(const String& input) {
+ return input;
+ }
+};
+
+template <size_t N>
+class TypeConverter<String, char[N]> {
+ public:
+ static String ConvertFrom(const char input[N]) {
+ assert(input);
+ return String(input, N-1);
+ }
+};
+
+// Appease MSVC.
+template <size_t N>
+class TypeConverter<String, const char[N]> {
+ public:
+ static String ConvertFrom(const char input[N]) {
+ assert(input);
+ return String(input, N-1);
+ }
+};
+
+template <>
+class TypeConverter<String, const char*> {
+ public:
+ // |input| may be null, in which case a null String will be returned.
+ static String ConvertFrom(const char* input) {
+ return String(input);
+ }
+};
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_STRING_H_
diff --git a/chromium/mojo/public/cpp/bindings/struct_ptr.h b/chromium/mojo/public/cpp/bindings/struct_ptr.h
new file mode 100644
index 00000000000..a4e55e758f4
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/struct_ptr.h
@@ -0,0 +1,154 @@
+// 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.
+
+#ifndef MOJO_PUBLIC_CPP_BINDINGS_STRUCT_PTR_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_STRUCT_PTR_H_
+
+#include <assert.h>
+
+#include <new>
+
+#include "mojo/public/cpp/system/macros.h"
+
+namespace mojo {
+namespace internal {
+
+template <typename Struct>
+class StructHelper {
+ public:
+ template <typename Ptr>
+ static void Initialize(Ptr* ptr) { ptr->Initialize(); }
+};
+
+} // namespace internal
+
+template <typename Struct>
+class StructPtr {
+ MOJO_MOVE_ONLY_TYPE_FOR_CPP_03(StructPtr, RValue);
+ public:
+ typedef typename Struct::Data_ Data_;
+
+ StructPtr() : ptr_(NULL) {}
+ ~StructPtr() {
+ delete ptr_;
+ }
+
+ StructPtr(RValue other) : ptr_(NULL) { Take(other.object); }
+ StructPtr& operator=(RValue other) {
+ Take(other.object);
+ return *this;
+ }
+
+ template <typename U>
+ U To() const {
+ return TypeConverter<StructPtr, U>::ConvertTo(*this);
+ }
+
+ void reset() {
+ if (ptr_) {
+ delete ptr_;
+ ptr_ = NULL;
+ }
+ }
+
+ bool is_null() const { return ptr_ == NULL; }
+
+ Struct& operator*() const {
+ assert(ptr_);
+ return *ptr_;
+ }
+ Struct* operator->() const {
+ assert(ptr_);
+ return ptr_;
+ }
+ Struct* get() const { return ptr_; }
+
+ void Swap(StructPtr* other) {
+ std::swap(ptr_, other->ptr_);
+ }
+
+ private:
+ typedef Struct* StructPtr::*Testable;
+
+ public:
+ operator Testable() const { return ptr_ ? &StructPtr::ptr_ : 0; }
+
+ private:
+ friend class internal::StructHelper<Struct>;
+ void Initialize() { assert(!ptr_); ptr_ = new Struct(); }
+
+ void Take(StructPtr* other) {
+ reset();
+ Swap(other);
+ }
+
+ Struct* ptr_;
+};
+
+// Designed to be used when Struct is small and copyable.
+template <typename Struct>
+class InlinedStructPtr {
+ MOJO_MOVE_ONLY_TYPE_FOR_CPP_03(InlinedStructPtr, RValue);
+ public:
+ typedef typename Struct::Data_ Data_;
+
+ InlinedStructPtr() : is_null_(true) {}
+ ~InlinedStructPtr() {}
+
+ InlinedStructPtr(RValue other) : is_null_(true) { Take(other.object); }
+ InlinedStructPtr& operator=(RValue other) {
+ Take(other.object);
+ return *this;
+ }
+
+ template <typename U>
+ U To() const {
+ return TypeConverter<InlinedStructPtr, U>::ConvertTo(*this);
+ }
+
+ void reset() {
+ is_null_ = true;
+ value_.~Struct();
+ new (&value_) Struct();
+ }
+
+ bool is_null() const { return is_null_; }
+
+ Struct& operator*() const {
+ assert(!is_null_);
+ return value_;
+ }
+ Struct* operator->() const {
+ assert(!is_null_);
+ return &value_;
+ }
+ Struct* get() const { return &value_; }
+
+ void Swap(InlinedStructPtr* other) {
+ std::swap(value_, other->value_);
+ std::swap(is_null_, other->is_null_);
+ }
+
+ private:
+ typedef Struct InlinedStructPtr::*Testable;
+
+ public:
+ operator Testable() const { return is_null_ ? 0 : &InlinedStructPtr::value_; }
+
+ private:
+ friend class internal::StructHelper<Struct>;
+ void Initialize() { is_null_ = false; }
+
+ void Take(InlinedStructPtr* other) {
+ reset();
+ Swap(other);
+ }
+
+ mutable Struct value_;
+ bool is_null_;
+};
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_STRUCT_PTR_H_
diff --git a/chromium/mojo/public/cpp/bindings/sync_dispatcher.h b/chromium/mojo/public/cpp/bindings/sync_dispatcher.h
new file mode 100644
index 00000000000..9f825bf8a6a
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/sync_dispatcher.h
@@ -0,0 +1,47 @@
+// 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.
+
+#ifndef MOJO_PUBLIC_CPP_BINDINGS_SYNC_DISPATCHER_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_SYNC_DISPATCHER_H_
+
+#include "mojo/public/cpp/bindings/lib/filter_chain.h"
+#include "mojo/public/cpp/bindings/lib/message_header_validator.h"
+#include "mojo/public/cpp/system/core.h"
+
+namespace mojo {
+
+class MessageReceiver;
+
+// Waits for one message to arrive on the message pipe, and dispatch it to the
+// receiver. Returns true on success, false on failure.
+//
+// NOTE: The message hasn't been validated and may be malformed!
+bool WaitForMessageAndDispatch(MessagePipeHandle handle,
+ mojo::MessageReceiver* receiver);
+
+template<typename Interface> class SyncDispatcher {
+ public:
+ SyncDispatcher(ScopedMessagePipeHandle message_pipe, Interface* sink)
+ : message_pipe_(message_pipe.Pass()) {
+ stub_.set_sink(sink);
+
+ filters_.Append<internal::MessageHeaderValidator>();
+ filters_.Append<typename Interface::RequestValidator_>();
+ filters_.SetSink(&stub_);
+ }
+
+ bool WaitAndDispatchOneMessage() {
+ return WaitForMessageAndDispatch(message_pipe_.get(),
+ filters_.GetHead());
+ }
+
+ private:
+ ScopedMessagePipeHandle message_pipe_;
+ typename Interface::Stub_ stub_;
+ internal::FilterChain filters_;
+};
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_SYNC_DISPATCHER_H_
diff --git a/chromium/mojo/public/cpp/bindings/type_converter.h b/chromium/mojo/public/cpp/bindings/type_converter.h
new file mode 100644
index 00000000000..0ac5f6d4760
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/type_converter.h
@@ -0,0 +1,82 @@
+// 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.
+
+#ifndef MOJO_PUBLIC_CPP_BINDINGS_TYPE_CONVERTER_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_TYPE_CONVERTER_H_
+
+namespace mojo {
+
+// Specialize the following class:
+// template <typename T, typename U> class TypeConverter;
+// to perform type conversion for Mojom-defined structs and arrays. Here, T is
+// the Mojom-defined struct or array, and U is some other non-Mojom
+// struct or array type.
+//
+// Specializations should implement the following interface:
+// namespace mojo {
+// template <>
+// class TypeConverter<T, U> {
+// public:
+// static T ConvertFrom(const U& input);
+// static U ConvertTo(const T& input);
+// };
+// }
+//
+// EXAMPLE:
+//
+// Suppose you have the following Mojom-defined struct:
+//
+// module geometry {
+// struct Point {
+// int32 x;
+// int32 y;
+// };
+// }
+//
+// Now, imagine you wanted to write a TypeConverter specialization for
+// gfx::Point. It might look like this:
+//
+// namespace mojo {
+// template <>
+// class TypeConverter<geometry::PointPtr, gfx::Point> {
+// public:
+// static geometry::PointPtr ConvertFrom(const gfx::Point& input) {
+// geometry::PointPtr result;
+// result->x = input.x();
+// result->y = input.y();
+// return result.Pass();
+// }
+// static gfx::Point ConvertTo(const geometry::PointPtr& input) {
+// return input ? gfx::Point(input->x, input->y) : gfx::Point();
+// }
+// };
+// }
+//
+// With the above TypeConverter defined, it is possible to write code like this:
+//
+// void AcceptPoint(const geometry::PointPtr& input) {
+// // With an explicit cast using the .To<> method.
+// gfx::Point pt = input.To<gfx::Point>();
+//
+// // With an explicit cast using the static From() method.
+// geometry::PointPtr output = geometry::Point::From(pt);
+// }
+//
+template <typename T, typename U> class TypeConverter;
+
+// The following specialization is useful when you are converting between
+// Array<POD> and std::vector<POD>.
+template <typename T> class TypeConverter<T, T> {
+ public:
+ static T ConvertFrom(const T& obj) {
+ return obj;
+ }
+ static T ConvertTo(const T& obj) {
+ return obj;
+ }
+};
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_TYPE_CONVERTER_H_
diff --git a/chromium/mojo/public/cpp/environment/environment.h b/chromium/mojo/public/cpp/environment/environment.h
new file mode 100644
index 00000000000..48f4c26eb72
--- /dev/null
+++ b/chromium/mojo/public/cpp/environment/environment.h
@@ -0,0 +1,41 @@
+// 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.
+
+#ifndef MOJO_PUBLIC_CPP_ENVIRONMENT_ENVIRONMENT_H_
+#define MOJO_PUBLIC_CPP_ENVIRONMENT_ENVIRONMENT_H_
+
+#include "mojo/public/cpp/system/macros.h"
+
+struct MojoAsyncWaiter;
+struct MojoLogger;
+
+namespace mojo {
+
+// Other parts of the Mojo C++ APIs use the *static* methods of this class.
+//
+// The "standalone" implementation of this class requires that this class (in
+// the lib/ subdirectory) be instantiated (and remain so) while using the Mojo
+// C++ APIs. I.e., the static methods depend on things set up by the constructor
+// and torn down by the destructor.
+//
+// Other implementations may not have this requirement.
+class Environment {
+ public:
+ Environment();
+ // This constructor allows the standard implementations to be overridden (set
+ // a parameter to null to get the standard implementation).
+ Environment(const MojoAsyncWaiter* default_async_waiter,
+ const MojoLogger* default_logger);
+ ~Environment();
+
+ static const MojoAsyncWaiter* GetDefaultAsyncWaiter();
+ static const MojoLogger* GetDefaultLogger();
+
+ private:
+ MOJO_DISALLOW_COPY_AND_ASSIGN(Environment);
+};
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_ENVIRONMENT_ENVIRONMENT_H_
diff --git a/chromium/mojo/public/cpp/environment/lib/DEPS b/chromium/mojo/public/cpp/environment/lib/DEPS
new file mode 100644
index 00000000000..1889e1fb75f
--- /dev/null
+++ b/chromium/mojo/public/cpp/environment/lib/DEPS
@@ -0,0 +1,4 @@
+include_rules = [
+ "+mojo/public/cpp/environment",
+ "+mojo/public/cpp/utility",
+]
diff --git a/chromium/mojo/public/cpp/environment/lib/default_async_waiter.cc b/chromium/mojo/public/cpp/environment/lib/default_async_waiter.cc
new file mode 100644
index 00000000000..257f1c8d797
--- /dev/null
+++ b/chromium/mojo/public/cpp/environment/lib/default_async_waiter.cc
@@ -0,0 +1,94 @@
+// 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/public/cpp/environment/lib/default_async_waiter.h"
+
+#include <assert.h>
+
+#include "mojo/public/c/environment/async_waiter.h"
+#include "mojo/public/cpp/utility/run_loop.h"
+#include "mojo/public/cpp/utility/run_loop_handler.h"
+
+namespace mojo {
+
+namespace {
+
+// RunLoopHandler implementation used for a request to AsyncWait(). There are
+// two ways RunLoopHandlerImpl is deleted:
+// . when the handle is ready (or errored).
+// . when CancelWait() is invoked.
+class RunLoopHandlerImpl : public RunLoopHandler {
+ public:
+ RunLoopHandlerImpl(const Handle& handle,
+ MojoAsyncWaitCallback callback,
+ void* closure)
+ : handle_(handle),
+ callback_(callback),
+ closure_(closure) {
+ }
+
+ virtual ~RunLoopHandlerImpl() {
+ RunLoop::current()->RemoveHandler(handle_);
+ }
+
+ // RunLoopHandler:
+ virtual void OnHandleReady(const Handle& handle) MOJO_OVERRIDE {
+ NotifyCallback(MOJO_RESULT_OK);
+ }
+
+ virtual void OnHandleError(const Handle& handle,
+ MojoResult result) MOJO_OVERRIDE {
+ NotifyCallback(result);
+ }
+
+ private:
+ void NotifyCallback(MojoResult result) {
+ // Delete this to unregister the handle. That way if the callback
+ // reregisters everything is ok.
+ MojoAsyncWaitCallback callback = callback_;
+ void* closure = closure_;
+ delete this;
+
+ callback(closure, result);
+ }
+
+ const Handle handle_;
+ MojoAsyncWaitCallback callback_;
+ void* closure_;
+
+ MOJO_DISALLOW_COPY_AND_ASSIGN(RunLoopHandlerImpl);
+};
+
+MojoAsyncWaitID AsyncWait(MojoHandle handle,
+ MojoHandleSignals signals,
+ MojoDeadline deadline,
+ MojoAsyncWaitCallback callback,
+ void* closure) {
+ RunLoop* run_loop = RunLoop::current();
+ assert(run_loop);
+
+ // |run_loop_handler| is destroyed either when the handle is ready or if
+ // CancelWait is invoked.
+ RunLoopHandlerImpl* run_loop_handler =
+ new RunLoopHandlerImpl(Handle(handle), callback, closure);
+ run_loop->AddHandler(run_loop_handler, Handle(handle), signals, deadline);
+ return reinterpret_cast<MojoAsyncWaitID>(run_loop_handler);
+}
+
+void CancelWait(MojoAsyncWaitID wait_id) {
+ delete reinterpret_cast<RunLoopHandlerImpl*>(wait_id);
+}
+
+} // namespace
+
+namespace internal {
+
+const MojoAsyncWaiter kDefaultAsyncWaiter = {
+ AsyncWait,
+ CancelWait
+};
+
+} // namespace internal
+
+} // namespace mojo
diff --git a/chromium/mojo/public/cpp/environment/lib/default_async_waiter.h b/chromium/mojo/public/cpp/environment/lib/default_async_waiter.h
new file mode 100644
index 00000000000..49ce233490c
--- /dev/null
+++ b/chromium/mojo/public/cpp/environment/lib/default_async_waiter.h
@@ -0,0 +1,18 @@
+// 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.
+
+#ifndef MOJO_PUBLIC_CPP_ENVIRONMENT_LIB_DEFAULT_ASYNC_WAITER_H_
+#define MOJO_PUBLIC_CPP_ENVIRONMENT_LIB_DEFAULT_ASYNC_WAITER_H_
+
+struct MojoAsyncWaiter;
+
+namespace mojo {
+namespace internal {
+
+extern const MojoAsyncWaiter kDefaultAsyncWaiter;
+
+} // namespace internal
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_ENVIRONMENT_LIB_DEFAULT_ASYNC_WAITER_H_
diff --git a/chromium/mojo/public/cpp/environment/lib/default_logger.cc b/chromium/mojo/public/cpp/environment/lib/default_logger.cc
new file mode 100644
index 00000000000..af4a62866b0
--- /dev/null
+++ b/chromium/mojo/public/cpp/environment/lib/default_logger.cc
@@ -0,0 +1,71 @@
+// 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/public/cpp/environment/lib/default_logger.h"
+
+#include <stdio.h>
+#include <stdlib.h> // For |abort()|.
+
+#include <algorithm>
+
+#include "mojo/public/c/environment/logger.h"
+
+namespace mojo {
+
+namespace {
+
+MojoLogLevel g_minimum_log_level = MOJO_LOG_LEVEL_INFO;
+
+const char* GetLogLevelString(MojoLogLevel log_level) {
+ if (log_level <= MOJO_LOG_LEVEL_VERBOSE-3)
+ return "VERBOSE4+";
+ switch (log_level) {
+ case MOJO_LOG_LEVEL_VERBOSE-2:
+ return "VERBOSE3";
+ case MOJO_LOG_LEVEL_VERBOSE-1:
+ return "VERBOSE2";
+ case MOJO_LOG_LEVEL_VERBOSE:
+ return "VERBOSE1";
+ case MOJO_LOG_LEVEL_INFO:
+ return "INFO";
+ case MOJO_LOG_LEVEL_WARNING:
+ return "WARNING";
+ case MOJO_LOG_LEVEL_ERROR:
+ return "ERROR";
+ }
+ // Consider everything higher to be fatal.
+ return "FATAL";
+}
+
+void LogMessage(MojoLogLevel log_level, const char* message) {
+ if (log_level < g_minimum_log_level)
+ return;
+
+ // TODO(vtl): Add timestamp also?
+ fprintf(stderr, "%s: %s\n", GetLogLevelString(log_level), message);
+ if (log_level >= MOJO_LOG_LEVEL_FATAL)
+ abort();
+}
+
+MojoLogLevel GetMinimumLogLevel() {
+ return g_minimum_log_level;
+}
+
+void SetMinimumLogLevel(MojoLogLevel minimum_log_level) {
+ g_minimum_log_level = std::min(minimum_log_level, MOJO_LOG_LEVEL_FATAL);
+}
+
+} // namespace
+
+namespace internal {
+
+const MojoLogger kDefaultLogger = {
+ LogMessage,
+ GetMinimumLogLevel,
+ SetMinimumLogLevel
+};
+
+} // namespace internal
+
+} // namespace mojo
diff --git a/chromium/mojo/public/cpp/environment/lib/default_logger.h b/chromium/mojo/public/cpp/environment/lib/default_logger.h
new file mode 100644
index 00000000000..4db32336811
--- /dev/null
+++ b/chromium/mojo/public/cpp/environment/lib/default_logger.h
@@ -0,0 +1,18 @@
+// 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.
+
+#ifndef MOJO_PUBLIC_CPP_ENVIRONMENT_LIB_DEFAULT_LOGGER_H_
+#define MOJO_PUBLIC_CPP_ENVIRONMENT_LIB_DEFAULT_LOGGER_H_
+
+struct MojoLogger;
+
+namespace mojo {
+namespace internal {
+
+extern const MojoLogger kDefaultLogger;
+
+} // namespace internal
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_ENVIRONMENT_LIB_DEFAULT_LOGGER_H_
diff --git a/chromium/mojo/public/cpp/environment/lib/environment.cc b/chromium/mojo/public/cpp/environment/lib/environment.cc
new file mode 100644
index 00000000000..58e270e9ae4
--- /dev/null
+++ b/chromium/mojo/public/cpp/environment/lib/environment.cc
@@ -0,0 +1,60 @@
+// 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/public/cpp/environment/environment.h"
+
+#include <stddef.h>
+
+#include "mojo/public/c/environment/logger.h"
+#include "mojo/public/cpp/environment/lib/default_async_waiter.h"
+#include "mojo/public/cpp/environment/lib/default_logger.h"
+#include "mojo/public/cpp/utility/run_loop.h"
+
+namespace mojo {
+
+namespace {
+
+const MojoAsyncWaiter* g_default_async_waiter = NULL;
+const MojoLogger* g_default_logger = NULL;
+
+void Init(const MojoAsyncWaiter* default_async_waiter,
+ const MojoLogger* default_logger) {
+ g_default_async_waiter =
+ default_async_waiter ? default_async_waiter :
+ &internal::kDefaultAsyncWaiter;
+ g_default_logger = default_logger ? default_logger :
+ &internal::kDefaultLogger;
+
+ RunLoop::SetUp();
+}
+
+} // namespace
+
+Environment::Environment() {
+ Init(NULL, NULL);
+}
+
+Environment::Environment(const MojoAsyncWaiter* default_async_waiter,
+ const MojoLogger* default_logger) {
+ Init(default_async_waiter, default_logger);
+}
+
+Environment::~Environment() {
+ RunLoop::TearDown();
+
+ // TODO(vtl): Maybe we should allow nesting, and restore previous default
+ // async waiters and loggers?
+}
+
+// static
+const MojoAsyncWaiter* Environment::GetDefaultAsyncWaiter() {
+ return g_default_async_waiter;
+}
+
+// static
+const MojoLogger* Environment::GetDefaultLogger() {
+ return g_default_logger;
+}
+
+} // namespace mojo
diff --git a/chromium/mojo/public/cpp/environment/lib/logging.cc b/chromium/mojo/public/cpp/environment/lib/logging.cc
new file mode 100644
index 00000000000..990626df736
--- /dev/null
+++ b/chromium/mojo/public/cpp/environment/lib/logging.cc
@@ -0,0 +1,45 @@
+// 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/public/cpp/environment/logging.h"
+
+#include "mojo/public/cpp/environment/environment.h"
+
+namespace mojo {
+namespace internal {
+
+namespace {
+
+// Gets a pointer to the filename portion of |s|. Assumes that the filename
+// follows the last slash or backslash in |s|, or is |s| if no slash or
+// backslash is present.
+//
+// E.g., a pointer to "foo.cc" is returned for the following inputs: "foo.cc",
+// "./foo.cc", ".\foo.cc", "/absolute/path/to/foo.cc",
+// "relative/path/to/foo.cc", "C:\absolute\path\to\foo.cc", etc.
+const char* GetFilename(const char* s) {
+ const char* rv = s;
+ while (*s) {
+ if (*s == '/' || *s == '\\')
+ rv = s + 1;
+ s++;
+ }
+ return rv;
+}
+
+} // namespace
+
+LogMessage::LogMessage(const char* file, int line, MojoLogLevel log_level)
+ : log_level_(log_level) {
+ // Note: Don't include the log level in the message, since that's passed on.
+ stream_ << GetFilename(file) << '(' << line << "): ";
+}
+
+LogMessage::~LogMessage() {
+ Environment::GetDefaultLogger()->LogMessage(log_level_,
+ stream_.str().c_str());
+}
+
+} // namespace internal
+} // namespace mojo
diff --git a/chromium/mojo/public/cpp/environment/logging.h b/chromium/mojo/public/cpp/environment/logging.h
new file mode 100644
index 00000000000..a3e2cef4293
--- /dev/null
+++ b/chromium/mojo/public/cpp/environment/logging.h
@@ -0,0 +1,87 @@
+// 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.
+
+// Logging macros, similar to Chromium's base/logging.h, except with |MOJO_|
+// prefixes and missing some features (notably |CHECK_EQ()|, etc.).
+
+// TODO(vtl): It's weird that this is in the environment directory, since its
+// implementation (in environment/lib) is meant to be used by any implementation
+// of the environment.
+
+#ifndef MOJO_PUBLIC_CPP_ENVIRONMENT_LOGGING_H_
+#define MOJO_PUBLIC_CPP_ENVIRONMENT_LOGGING_H_
+
+#include <sstream>
+
+#include "mojo/public/c/environment/logger.h"
+#include "mojo/public/cpp/environment/environment.h"
+#include "mojo/public/cpp/system/macros.h"
+
+#define MOJO_LOG_STREAM(level) \
+ ::mojo::internal::LogMessage(__FILE__, __LINE__, \
+ MOJO_LOG_LEVEL_ ## level).stream()
+
+#define MOJO_LAZY_LOG_STREAM(level, condition) \
+ !(condition) ? \
+ (void) 0 : \
+ ::mojo::internal::VoidifyOstream() & MOJO_LOG_STREAM(level)
+
+#define MOJO_SHOULD_LOG(level) \
+ (MOJO_LOG_LEVEL_ ## level >= \
+ ::mojo::Environment::GetDefaultLogger()->GetMinimumLogLevel())
+
+#define MOJO_LOG(level) \
+ MOJO_LAZY_LOG_STREAM(level, MOJO_SHOULD_LOG(level))
+
+#define MOJO_LOG_IF(level, condition) \
+ MOJO_LAZY_LOG_STREAM(level, MOJO_SHOULD_LOG(level) && (condition))
+
+#define MOJO_CHECK(condition) \
+ MOJO_LAZY_LOG_STREAM(FATAL, !(condition)) \
+ << "Check failed: " #condition ". "
+
+// Note: For non-debug builds, |MOJO_DLOG_IF()| *eliminates* (i.e., doesn't
+// compile) the condition, whereas |MOJO_DCHECK()| "neuters" the condition
+// (i.e., compiles, but doesn't evaluate).
+#ifdef NDEBUG
+
+#define MOJO_DLOG(level) MOJO_LAZY_LOG_STREAM(level, false)
+#define MOJO_DLOG_IF(level, condition) MOJO_LAZY_LOG_STREAM(level, false)
+#define MOJO_DCHECK(condition) MOJO_LAZY_LOG_STREAM(FATAL, false && (condition))
+
+#else
+
+#define MOJO_DLOG(level) MOJO_LOG(level)
+#define MOJO_DLOG_IF(level, condition) MOJO_LOG_IF(level, condition)
+#define MOJO_DCHECK(condition) MOJO_CHECK(condition)
+
+#endif // NDEBUG
+
+namespace mojo {
+namespace internal {
+
+class LogMessage {
+ public:
+ LogMessage(const char* file, int line, MojoLogLevel log_level);
+ ~LogMessage();
+
+ std::ostream& stream() { return stream_; }
+
+ private:
+ const MojoLogLevel log_level_;
+ std::ostringstream stream_;
+
+ MOJO_DISALLOW_COPY_AND_ASSIGN(LogMessage);
+};
+
+// Used to ignore a stream.
+struct VoidifyOstream {
+ // Use & since it has precedence lower than << but higher than ?:.
+ void operator&(std::ostream&) {}
+};
+
+} // namespace internal
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_ENVIRONMENT_LOGGING_H_
diff --git a/chromium/mojo/public/cpp/gles2/DEPS b/chromium/mojo/public/cpp/gles2/DEPS
new file mode 100644
index 00000000000..3c48be99eb8
--- /dev/null
+++ b/chromium/mojo/public/cpp/gles2/DEPS
@@ -0,0 +1,4 @@
+include_rules = [
+ "+mojo/public/c/gles2",
+ "+mojo/public/cpp/environment",
+]
diff --git a/chromium/mojo/public/cpp/gles2/gles2.h b/chromium/mojo/public/cpp/gles2/gles2.h
new file mode 100644
index 00000000000..a408fc701eb
--- /dev/null
+++ b/chromium/mojo/public/cpp/gles2/gles2.h
@@ -0,0 +1,24 @@
+// 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.
+
+#ifndef MOJO_PUBLIC_CPP_GLES2_GLES2_H_
+#define MOJO_PUBLIC_CPP_GLES2_GLES2_H_
+
+#include "mojo/public/c/gles2/gles2.h"
+#include "mojo/public/cpp/environment/environment.h"
+
+namespace mojo {
+
+class GLES2Initializer {
+ public:
+ explicit GLES2Initializer(const MojoAsyncWaiter* async_waiter =
+ Environment::GetDefaultAsyncWaiter()) {
+ MojoGLES2Initialize(async_waiter);
+ }
+ ~GLES2Initializer() { MojoGLES2Terminate(); }
+};
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_GLES2_GLES2_H_
diff --git a/chromium/mojo/public/cpp/system/core.h b/chromium/mojo/public/cpp/system/core.h
new file mode 100644
index 00000000000..d73bb296514
--- /dev/null
+++ b/chromium/mojo/public/cpp/system/core.h
@@ -0,0 +1,555 @@
+// Copyright 2013 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.
+
+#ifndef MOJO_PUBLIC_CPP_SYSTEM_CORE_H_
+#define MOJO_PUBLIC_CPP_SYSTEM_CORE_H_
+
+#include <assert.h>
+#include <stddef.h>
+
+#include <limits>
+
+#include "mojo/public/c/system/core.h"
+#include "mojo/public/c/system/system_export.h"
+#include "mojo/public/cpp/system/macros.h"
+
+namespace mojo {
+
+// OVERVIEW
+//
+// |Handle| and |...Handle|:
+//
+// |Handle| is a simple, copyable wrapper for the C type |MojoHandle| (which is
+// just an integer). Its purpose is to increase type-safety, not provide
+// lifetime management. For the same purpose, we have trivial *subclasses* of
+// |Handle|, e.g., |MessagePipeHandle| and |DataPipeProducerHandle|. |Handle|
+// and its subclasses impose *no* extra overhead over using |MojoHandle|s
+// directly.
+//
+// Note that though we provide constructors for |Handle|/|...Handle| from a
+// |MojoHandle|, we do not provide, e.g., a constructor for |MessagePipeHandle|
+// from a |Handle|. This is for type safety: If we did, you'd then be able to
+// construct a |MessagePipeHandle| from, e.g., a |DataPipeProducerHandle| (since
+// it's a |Handle|).
+//
+// |ScopedHandleBase| and |Scoped...Handle|:
+//
+// |ScopedHandleBase<HandleType>| is a templated scoped wrapper, for the handle
+// types above (in the same sense that a C++11 |unique_ptr<T>| is a scoped
+// wrapper for a |T*|). It provides lifetime management, closing its owned
+// handle on destruction. It also provides (emulated) move semantics, again
+// along the lines of C++11's |unique_ptr| (and exactly like Chromium's
+// |scoped_ptr|).
+//
+// |ScopedHandle| is just (a typedef of) a |ScopedHandleBase<Handle>|.
+// Similarly, |ScopedMessagePipeHandle| is just a
+// |ScopedHandleBase<MessagePipeHandle>|. Etc. Note that a
+// |ScopedMessagePipeHandle| is *not* a (subclass of) |ScopedHandle|.
+//
+// Wrapper functions:
+//
+// We provide simple wrappers for the |Mojo...()| functions (in
+// mojo/public/c/system/core.h -- see that file for details on individual
+// functions).
+//
+// The general guideline is functions that imply ownership transfer of a handle
+// should take (or produce) an appropriate |Scoped...Handle|, while those that
+// don't take a |...Handle|. For example, |CreateMessagePipe()| has two
+// |ScopedMessagePipe| "out" parameters, whereas |Wait()| and |WaitMany()| take
+// |Handle| parameters. Some, have both: e.g., |DuplicatedBuffer()| takes a
+// suitable (unscoped) handle (e.g., |SharedBufferHandle|) "in" parameter and
+// produces a suitable scoped handle (e.g., |ScopedSharedBufferHandle| a.k.a.
+// |ScopedHandleBase<SharedBufferHandle>|) as an "out" parameter.
+//
+// An exception are some of the |...Raw()| functions. E.g., |CloseRaw()| takes a
+// |Handle|, leaving the user to discard the handle.
+//
+// More significantly, |WriteMessageRaw()| exposes the full API complexity of
+// |MojoWriteMessage()| (but doesn't require any extra overhead). It takes a raw
+// array of |Handle|s as input, and takes ownership of them (i.e., invalidates
+// them) on *success* (but not on failure). There are a number of reasons for
+// this. First, C++03 |std::vector|s cannot contain the move-only
+// |Scoped...Handle|s. Second, |std::vector|s impose extra overhead
+// (necessitating heap-allocation of the buffer). Third, |std::vector|s wouldn't
+// provide the desired level of flexibility/safety: a vector of handles would
+// have to be all of the same type (probably |Handle|/|ScopedHandle|). Fourth,
+// it's expected to not be used directly, but instead be used by generated
+// bindings.
+//
+// Other |...Raw()| functions expose similar rough edges, e.g., dealing with raw
+// pointers (and lengths) instead of taking |std::vector|s or similar.
+
+// Standalone functions --------------------------------------------------------
+
+inline MojoTimeTicks GetTimeTicksNow() {
+ return MojoGetTimeTicksNow();
+}
+
+// ScopedHandleBase ------------------------------------------------------------
+
+// Scoper for the actual handle types defined further below. It's move-only,
+// like the C++11 |unique_ptr|.
+template <class HandleType>
+class ScopedHandleBase {
+ MOJO_MOVE_ONLY_TYPE_FOR_CPP_03(ScopedHandleBase, RValue)
+
+ public:
+ ScopedHandleBase() {}
+ explicit ScopedHandleBase(HandleType handle) : handle_(handle) {}
+ ~ScopedHandleBase() { CloseIfNecessary(); }
+
+ template <class CompatibleHandleType>
+ explicit ScopedHandleBase(ScopedHandleBase<CompatibleHandleType> other)
+ : handle_(other.release()) {
+ }
+
+ // Move-only constructor and operator=.
+ ScopedHandleBase(RValue other) : handle_(other.object->release()) {}
+ ScopedHandleBase& operator=(RValue other) {
+ if (other.object != this) {
+ CloseIfNecessary();
+ handle_ = other.object->release();
+ }
+ return *this;
+ }
+
+ const HandleType& get() const { return handle_; }
+
+ template <typename PassedHandleType>
+ static ScopedHandleBase<HandleType> From(
+ ScopedHandleBase<PassedHandleType> other) {
+ MOJO_COMPILE_ASSERT(
+ sizeof(static_cast<PassedHandleType*>(static_cast<HandleType*>(0))),
+ HandleType_is_not_a_subtype_of_PassedHandleType);
+ return ScopedHandleBase<HandleType>(
+ static_cast<HandleType>(other.release().value()));
+ }
+
+ void swap(ScopedHandleBase& other) {
+ handle_.swap(other.handle_);
+ }
+
+ HandleType release() MOJO_WARN_UNUSED_RESULT {
+ HandleType rv;
+ rv.swap(handle_);
+ return rv;
+ }
+
+ void reset(HandleType handle = HandleType()) {
+ CloseIfNecessary();
+ handle_ = handle;
+ }
+
+ bool is_valid() const {
+ return handle_.is_valid();
+ }
+
+ private:
+ void CloseIfNecessary() {
+ if (!handle_.is_valid())
+ return;
+ MojoResult result MOJO_ALLOW_UNUSED = MojoClose(handle_.value());
+ assert(result == MOJO_RESULT_OK);
+ }
+
+ HandleType handle_;
+};
+
+template <typename HandleType>
+inline ScopedHandleBase<HandleType> MakeScopedHandle(HandleType handle) {
+ return ScopedHandleBase<HandleType>(handle);
+}
+
+// Handle ----------------------------------------------------------------------
+
+const MojoHandle kInvalidHandleValue = MOJO_HANDLE_INVALID;
+
+// Wrapper base class for |MojoHandle|.
+class Handle {
+ public:
+ Handle() : value_(kInvalidHandleValue) {}
+ explicit Handle(MojoHandle value) : value_(value) {}
+ ~Handle() {}
+
+ void swap(Handle& other) {
+ MojoHandle temp = value_;
+ value_ = other.value_;
+ other.value_ = temp;
+ }
+
+ bool is_valid() const {
+ return value_ != kInvalidHandleValue;
+ }
+
+ MojoHandle value() const { return value_; }
+ MojoHandle* mutable_value() { return &value_; }
+ void set_value(MojoHandle value) { value_ = value; }
+
+ private:
+ MojoHandle value_;
+
+ // Copying and assignment allowed.
+};
+
+// Should have zero overhead.
+MOJO_COMPILE_ASSERT(sizeof(Handle) == sizeof(MojoHandle),
+ bad_size_for_cpp_Handle);
+
+// The scoper should also impose no more overhead.
+typedef ScopedHandleBase<Handle> ScopedHandle;
+MOJO_COMPILE_ASSERT(sizeof(ScopedHandle) == sizeof(Handle),
+ bad_size_for_cpp_ScopedHandle);
+
+inline MojoResult Wait(const Handle& handle,
+ MojoHandleSignals signals,
+ MojoDeadline deadline) {
+ return MojoWait(handle.value(), signals, deadline);
+}
+
+// |HandleVectorType| and |FlagsVectorType| should be similar enough to
+// |std::vector<Handle>| and |std::vector<MojoHandleSignals>|, respectively:
+// - They should have a (const) |size()| method that returns an unsigned type.
+// - They must provide contiguous storage, with access via (const) reference to
+// that storage provided by a (const) |operator[]()| (by reference).
+template <class HandleVectorType, class FlagsVectorType>
+inline MojoResult WaitMany(const HandleVectorType& handles,
+ const FlagsVectorType& signals,
+ MojoDeadline deadline) {
+ if (signals.size() != handles.size())
+ return MOJO_RESULT_INVALID_ARGUMENT;
+ if (handles.size() > std::numeric_limits<uint32_t>::max())
+ return MOJO_RESULT_OUT_OF_RANGE;
+
+ if (handles.size() == 0)
+ return MojoWaitMany(NULL, NULL, 0, deadline);
+
+ const Handle& first_handle = handles[0];
+ const MojoHandleSignals& first_signals = signals[0];
+ return MojoWaitMany(
+ reinterpret_cast<const MojoHandle*>(&first_handle),
+ reinterpret_cast<const MojoHandleSignals*>(&first_signals),
+ static_cast<uint32_t>(handles.size()),
+ deadline);
+}
+
+// |Close()| takes ownership of the handle, since it'll invalidate it.
+// Note: There's nothing to do, since the argument will be destroyed when it
+// goes out of scope.
+template <class HandleType>
+inline void Close(ScopedHandleBase<HandleType> /*handle*/) {}
+
+// Most users should typically use |Close()| (above) instead.
+inline MojoResult CloseRaw(Handle handle) {
+ return MojoClose(handle.value());
+}
+
+// Strict weak ordering, so that |Handle|s can be used as keys in |std::map|s,
+// etc.
+inline bool operator<(const Handle& a, const Handle& b) {
+ return a.value() < b.value();
+}
+
+// MessagePipeHandle -----------------------------------------------------------
+
+class MessagePipeHandle : public Handle {
+ public:
+ MessagePipeHandle() {}
+ explicit MessagePipeHandle(MojoHandle value) : Handle(value) {}
+
+ // Copying and assignment allowed.
+};
+
+MOJO_COMPILE_ASSERT(sizeof(MessagePipeHandle) == sizeof(Handle),
+ bad_size_for_cpp_MessagePipeHandle);
+
+typedef ScopedHandleBase<MessagePipeHandle> ScopedMessagePipeHandle;
+MOJO_COMPILE_ASSERT(sizeof(ScopedMessagePipeHandle) ==
+ sizeof(MessagePipeHandle),
+ bad_size_for_cpp_ScopedMessagePipeHandle);
+
+inline MojoResult CreateMessagePipe(const MojoCreateMessagePipeOptions* options,
+ ScopedMessagePipeHandle* message_pipe0,
+ ScopedMessagePipeHandle* message_pipe1) {
+ assert(message_pipe0);
+ assert(message_pipe1);
+ MessagePipeHandle handle0;
+ MessagePipeHandle handle1;
+ MojoResult rv = MojoCreateMessagePipe(options,
+ handle0.mutable_value(),
+ handle1.mutable_value());
+ // Reset even on failure (reduces the chances that a "stale"/incorrect handle
+ // will be used).
+ message_pipe0->reset(handle0);
+ message_pipe1->reset(handle1);
+ return rv;
+}
+
+// These "raw" versions fully expose the underlying API, but don't help with
+// ownership of handles (especially when writing messages).
+// TODO(vtl): Write "baked" versions.
+inline MojoResult WriteMessageRaw(MessagePipeHandle message_pipe,
+ const void* bytes,
+ uint32_t num_bytes,
+ const MojoHandle* handles,
+ uint32_t num_handles,
+ MojoWriteMessageFlags flags) {
+ return MojoWriteMessage(message_pipe.value(), bytes, num_bytes, handles,
+ num_handles, flags);
+}
+
+inline MojoResult ReadMessageRaw(MessagePipeHandle message_pipe,
+ void* bytes,
+ uint32_t* num_bytes,
+ MojoHandle* handles,
+ uint32_t* num_handles,
+ MojoReadMessageFlags flags) {
+ return MojoReadMessage(message_pipe.value(), bytes, num_bytes, handles,
+ num_handles, flags);
+}
+
+// A wrapper class that automatically creates a message pipe and owns both
+// handles.
+class MessagePipe {
+ public:
+ MessagePipe();
+ explicit MessagePipe(const MojoCreateMessagePipeOptions& options);
+ ~MessagePipe();
+
+ ScopedMessagePipeHandle handle0;
+ ScopedMessagePipeHandle handle1;
+};
+
+inline MessagePipe::MessagePipe() {
+ MojoResult result MOJO_ALLOW_UNUSED =
+ CreateMessagePipe(NULL, &handle0, &handle1);
+ assert(result == MOJO_RESULT_OK);
+}
+
+inline MessagePipe::MessagePipe(const MojoCreateMessagePipeOptions& options) {
+ MojoResult result MOJO_ALLOW_UNUSED =
+ CreateMessagePipe(&options, &handle0, &handle1);
+ assert(result == MOJO_RESULT_OK);
+}
+
+inline MessagePipe::~MessagePipe() {
+}
+
+// DataPipeProducerHandle and DataPipeConsumerHandle ---------------------------
+
+class DataPipeProducerHandle : public Handle {
+ public:
+ DataPipeProducerHandle() {}
+ explicit DataPipeProducerHandle(MojoHandle value) : Handle(value) {}
+
+ // Copying and assignment allowed.
+};
+
+MOJO_COMPILE_ASSERT(sizeof(DataPipeProducerHandle) == sizeof(Handle),
+ bad_size_for_cpp_DataPipeProducerHandle);
+
+typedef ScopedHandleBase<DataPipeProducerHandle> ScopedDataPipeProducerHandle;
+MOJO_COMPILE_ASSERT(sizeof(ScopedDataPipeProducerHandle) ==
+ sizeof(DataPipeProducerHandle),
+ bad_size_for_cpp_ScopedDataPipeProducerHandle);
+
+class DataPipeConsumerHandle : public Handle {
+ public:
+ DataPipeConsumerHandle() {}
+ explicit DataPipeConsumerHandle(MojoHandle value) : Handle(value) {}
+
+ // Copying and assignment allowed.
+};
+
+MOJO_COMPILE_ASSERT(sizeof(DataPipeConsumerHandle) == sizeof(Handle),
+ bad_size_for_cpp_DataPipeConsumerHandle);
+
+typedef ScopedHandleBase<DataPipeConsumerHandle> ScopedDataPipeConsumerHandle;
+MOJO_COMPILE_ASSERT(sizeof(ScopedDataPipeConsumerHandle) ==
+ sizeof(DataPipeConsumerHandle),
+ bad_size_for_cpp_ScopedDataPipeConsumerHandle);
+
+inline MojoResult CreateDataPipe(
+ const MojoCreateDataPipeOptions* options,
+ ScopedDataPipeProducerHandle* data_pipe_producer,
+ ScopedDataPipeConsumerHandle* data_pipe_consumer) {
+ assert(data_pipe_producer);
+ assert(data_pipe_consumer);
+ DataPipeProducerHandle producer_handle;
+ DataPipeConsumerHandle consumer_handle;
+ MojoResult rv = MojoCreateDataPipe(options, producer_handle.mutable_value(),
+ consumer_handle.mutable_value());
+ // Reset even on failure (reduces the chances that a "stale"/incorrect handle
+ // will be used).
+ data_pipe_producer->reset(producer_handle);
+ data_pipe_consumer->reset(consumer_handle);
+ return rv;
+}
+
+inline MojoResult WriteDataRaw(DataPipeProducerHandle data_pipe_producer,
+ const void* elements,
+ uint32_t* num_bytes,
+ MojoWriteDataFlags flags) {
+ return MojoWriteData(data_pipe_producer.value(), elements, num_bytes, flags);
+}
+
+inline MojoResult BeginWriteDataRaw(DataPipeProducerHandle data_pipe_producer,
+ void** buffer,
+ uint32_t* buffer_num_bytes,
+ MojoWriteDataFlags flags) {
+ return MojoBeginWriteData(data_pipe_producer.value(), buffer,
+ buffer_num_bytes, flags);
+}
+
+inline MojoResult EndWriteDataRaw(DataPipeProducerHandle data_pipe_producer,
+ uint32_t num_bytes_written) {
+ return MojoEndWriteData(data_pipe_producer.value(), num_bytes_written);
+}
+
+inline MojoResult ReadDataRaw(DataPipeConsumerHandle data_pipe_consumer,
+ void* elements,
+ uint32_t* num_bytes,
+ MojoReadDataFlags flags) {
+ return MojoReadData(data_pipe_consumer.value(), elements, num_bytes, flags);
+}
+
+inline MojoResult BeginReadDataRaw(DataPipeConsumerHandle data_pipe_consumer,
+ const void** buffer,
+ uint32_t* buffer_num_bytes,
+ MojoReadDataFlags flags) {
+ return MojoBeginReadData(data_pipe_consumer.value(), buffer, buffer_num_bytes,
+ flags);
+}
+
+inline MojoResult EndReadDataRaw(DataPipeConsumerHandle data_pipe_consumer,
+ uint32_t num_bytes_read) {
+ return MojoEndReadData(data_pipe_consumer.value(), num_bytes_read);
+}
+
+// A wrapper class that automatically creates a data pipe and owns both handles.
+// TODO(vtl): Make an even more friendly version? (Maybe templatized for a
+// particular type instead of some "element"? Maybe functions that take
+// vectors?)
+class DataPipe {
+ public:
+ DataPipe();
+ explicit DataPipe(const MojoCreateDataPipeOptions& options);
+ ~DataPipe();
+
+ ScopedDataPipeProducerHandle producer_handle;
+ ScopedDataPipeConsumerHandle consumer_handle;
+};
+
+inline DataPipe::DataPipe() {
+ MojoResult result MOJO_ALLOW_UNUSED =
+ CreateDataPipe(NULL, &producer_handle, &consumer_handle);
+ assert(result == MOJO_RESULT_OK);
+}
+
+inline DataPipe::DataPipe(const MojoCreateDataPipeOptions& options) {
+ MojoResult result MOJO_ALLOW_UNUSED =
+ CreateDataPipe(&options, &producer_handle, &consumer_handle);
+ assert(result == MOJO_RESULT_OK);
+}
+
+inline DataPipe::~DataPipe() {
+}
+
+// SharedBufferHandle ----------------------------------------------------------
+
+class SharedBufferHandle : public Handle {
+ public:
+ SharedBufferHandle() {}
+ explicit SharedBufferHandle(MojoHandle value) : Handle(value) {}
+
+ // Copying and assignment allowed.
+};
+
+MOJO_COMPILE_ASSERT(sizeof(SharedBufferHandle) == sizeof(Handle),
+ bad_size_for_cpp_SharedBufferHandle);
+
+typedef ScopedHandleBase<SharedBufferHandle> ScopedSharedBufferHandle;
+MOJO_COMPILE_ASSERT(sizeof(ScopedSharedBufferHandle) ==
+ sizeof(SharedBufferHandle),
+ bad_size_for_cpp_ScopedSharedBufferHandle);
+
+inline MojoResult CreateSharedBuffer(
+ const MojoCreateSharedBufferOptions* options,
+ uint64_t num_bytes,
+ ScopedSharedBufferHandle* shared_buffer) {
+ assert(shared_buffer);
+ SharedBufferHandle handle;
+ MojoResult rv = MojoCreateSharedBuffer(options, num_bytes,
+ handle.mutable_value());
+ // Reset even on failure (reduces the chances that a "stale"/incorrect handle
+ // will be used).
+ shared_buffer->reset(handle);
+ return rv;
+}
+
+// TODO(vtl): This (and also the functions below) are templatized to allow for
+// future/other buffer types. A bit "safer" would be to overload this function
+// manually. (The template enforces that the in and out handles to be of the
+// same type.)
+template <class BufferHandleType>
+inline MojoResult DuplicateBuffer(
+ BufferHandleType buffer,
+ const MojoDuplicateBufferHandleOptions* options,
+ ScopedHandleBase<BufferHandleType>* new_buffer) {
+ assert(new_buffer);
+ BufferHandleType handle;
+ MojoResult rv = MojoDuplicateBufferHandle(
+ buffer.value(), options, handle.mutable_value());
+ // Reset even on failure (reduces the chances that a "stale"/incorrect handle
+ // will be used).
+ new_buffer->reset(handle);
+ return rv;
+}
+
+template <class BufferHandleType>
+inline MojoResult MapBuffer(BufferHandleType buffer,
+ uint64_t offset,
+ uint64_t num_bytes,
+ void** pointer,
+ MojoMapBufferFlags flags) {
+ assert(buffer.is_valid());
+ return MojoMapBuffer(buffer.value(), offset, num_bytes, pointer, flags);
+}
+
+inline MojoResult UnmapBuffer(void* pointer) {
+ assert(pointer);
+ return MojoUnmapBuffer(pointer);
+}
+
+// A wrapper class that automatically creates a shared buffer and owns the
+// handle.
+class SharedBuffer {
+ public:
+ explicit SharedBuffer(uint64_t num_bytes);
+ SharedBuffer(uint64_t num_bytes,
+ const MojoCreateSharedBufferOptions& options);
+ ~SharedBuffer();
+
+ ScopedSharedBufferHandle handle;
+};
+
+inline SharedBuffer::SharedBuffer(uint64_t num_bytes) {
+ MojoResult result MOJO_ALLOW_UNUSED =
+ CreateSharedBuffer(NULL, num_bytes, &handle);
+ assert(result == MOJO_RESULT_OK);
+}
+
+inline SharedBuffer::SharedBuffer(
+ uint64_t num_bytes,
+ const MojoCreateSharedBufferOptions& options) {
+ MojoResult result MOJO_ALLOW_UNUSED =
+ CreateSharedBuffer(&options, num_bytes, &handle);
+ assert(result == MOJO_RESULT_OK);
+}
+
+inline SharedBuffer::~SharedBuffer() {
+}
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_SYSTEM_CORE_H_
diff --git a/chromium/mojo/public/cpp/system/macros.h b/chromium/mojo/public/cpp/system/macros.h
new file mode 100644
index 00000000000..ac4f3dbc84c
--- /dev/null
+++ b/chromium/mojo/public/cpp/system/macros.h
@@ -0,0 +1,53 @@
+// Copyright 2013 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.
+
+#ifndef MOJO_PUBLIC_CPP_SYSTEM_MACROS_H_
+#define MOJO_PUBLIC_CPP_SYSTEM_MACROS_H_
+
+#include "mojo/public/c/system/macros.h"
+
+// Annotate a virtual method indicating it must be overriding a virtual method
+// in the parent class. Use like:
+// virtual void foo() OVERRIDE;
+#if defined(_MSC_VER) || defined(__clang__)
+#define MOJO_OVERRIDE override
+#else
+#define MOJO_OVERRIDE
+#endif
+
+// A macro to disallow the copy constructor and operator= functions.
+// This should be used in the private: declarations for a class.
+#define MOJO_DISALLOW_COPY_AND_ASSIGN(TypeName) \
+ TypeName(const TypeName&); \
+ void operator=(const TypeName&)
+
+// Used to calculate the number of elements in an array.
+// (See |arraysize()| in Chromium's base/basictypes.h for more details.)
+namespace mojo {
+template <typename T, size_t N>
+char (&ArraySizeHelper(T (&array)[N]))[N];
+#if !defined(_MSC_VER)
+template <typename T, size_t N>
+char (&ArraySizeHelper(const T (&array)[N]))[N];
+#endif
+} // namespace mojo
+#define MOJO_ARRAYSIZE(array) (sizeof(::mojo::ArraySizeHelper(array)))
+
+// Used to make a type move-only in C++03. See Chromium's base/move.h for more
+// details.
+#define MOJO_MOVE_ONLY_TYPE_FOR_CPP_03(type, rvalue_type) \
+ private: \
+ struct rvalue_type { \
+ explicit rvalue_type(type* object) : object(object) {} \
+ type* object; \
+ }; \
+ type(type&); \
+ void operator=(type&); \
+ public: \
+ operator rvalue_type() { return rvalue_type(this); } \
+ type Pass() { return type(rvalue_type(this)); } \
+ typedef void MoveOnlyTypeForCPP03; \
+ private:
+
+#endif // MOJO_PUBLIC_CPP_SYSTEM_MACROS_H_
diff --git a/chromium/mojo/public/cpp/test_support/DEPS b/chromium/mojo/public/cpp/test_support/DEPS
new file mode 100644
index 00000000000..6dc53942e16
--- /dev/null
+++ b/chromium/mojo/public/cpp/test_support/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+ "+mojo/public/c/test_support",
+]
diff --git a/chromium/mojo/public/cpp/test_support/lib/test_support.cc b/chromium/mojo/public/cpp/test_support/lib/test_support.cc
new file mode 100644
index 00000000000..55a3dcc7024
--- /dev/null
+++ b/chromium/mojo/public/cpp/test_support/lib/test_support.cc
@@ -0,0 +1,26 @@
+// 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/public/cpp/test_support/test_support.h"
+
+#include <stdlib.h>
+
+namespace mojo {
+namespace test {
+
+std::vector<std::string> EnumerateSourceRootRelativeDirectory(
+ const std::string& relative_path) {
+ char** names = MojoTestSupportEnumerateSourceRootRelativeDirectory(
+ relative_path.c_str());
+ std::vector<std::string> results;
+ for (char** ptr = names; *ptr != NULL; ++ptr) {
+ results.push_back(*ptr);
+ free(*ptr);
+ }
+ free(names);
+ return results;
+}
+
+} // namespace test
+} // namespace mojo
diff --git a/chromium/mojo/public/cpp/test_support/lib/test_utils.cc b/chromium/mojo/public/cpp/test_support/lib/test_utils.cc
new file mode 100644
index 00000000000..b47ea209020
--- /dev/null
+++ b/chromium/mojo/public/cpp/test_support/lib/test_utils.cc
@@ -0,0 +1,91 @@
+// Copyright 2013 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/public/cpp/test_support/test_utils.h"
+
+#include "mojo/public/cpp/system/core.h"
+#include "mojo/public/cpp/test_support/test_support.h"
+
+namespace mojo {
+namespace test {
+
+bool WriteTextMessage(const MessagePipeHandle& handle,
+ const std::string& text) {
+ MojoResult rv = WriteMessageRaw(handle,
+ text.data(),
+ static_cast<uint32_t>(text.size()),
+ NULL,
+ 0,
+ MOJO_WRITE_MESSAGE_FLAG_NONE);
+ return rv == MOJO_RESULT_OK;
+}
+
+bool ReadTextMessage(const MessagePipeHandle& handle, std::string* text) {
+ MojoResult rv;
+ bool did_wait = false;
+
+ uint32_t num_bytes = 0, num_handles = 0;
+ for (;;) {
+ rv = ReadMessageRaw(handle,
+ NULL,
+ &num_bytes,
+ NULL,
+ &num_handles,
+ MOJO_READ_MESSAGE_FLAG_NONE);
+ if (rv == MOJO_RESULT_SHOULD_WAIT) {
+ if (did_wait) {
+ assert(false); // Looping endlessly!?
+ return false;
+ }
+ rv = Wait(handle, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE);
+ if (rv != MOJO_RESULT_OK)
+ return false;
+ did_wait = true;
+ } else {
+ assert(!num_handles);
+ break;
+ }
+ }
+
+ text->resize(num_bytes);
+ rv = ReadMessageRaw(handle,
+ &text->at(0),
+ &num_bytes,
+ NULL,
+ &num_handles,
+ MOJO_READ_MESSAGE_FLAG_NONE);
+ return rv == MOJO_RESULT_OK;
+}
+
+bool DiscardMessage(const MessagePipeHandle& handle) {
+ MojoResult rv = ReadMessageRaw(handle, NULL, NULL, NULL, NULL,
+ MOJO_READ_MESSAGE_FLAG_MAY_DISCARD);
+ return rv == MOJO_RESULT_OK;
+}
+
+void IterateAndReportPerf(const char* test_name,
+ PerfTestSingleIteration single_iteration,
+ void* closure) {
+ // TODO(vtl): These should be specifiable using command-line flags.
+ static const size_t kGranularity = 100;
+ static const MojoTimeTicks kPerftestTimeMicroseconds = 3 * 1000000;
+
+ const MojoTimeTicks start_time = GetTimeTicksNow();
+ MojoTimeTicks end_time;
+ size_t iterations = 0;
+ do {
+ for (size_t i = 0; i < kGranularity; i++)
+ (*single_iteration)(closure);
+ iterations += kGranularity;
+
+ end_time = GetTimeTicksNow();
+ } while (end_time - start_time < kPerftestTimeMicroseconds);
+
+ MojoTestSupportLogPerfResult(test_name,
+ 1000000.0 * iterations / (end_time - start_time),
+ "iterations/second");
+}
+
+} // namespace test
+} // namespace mojo
diff --git a/chromium/mojo/public/cpp/test_support/test_support.h b/chromium/mojo/public/cpp/test_support/test_support.h
new file mode 100644
index 00000000000..eb4d4be7116
--- /dev/null
+++ b/chromium/mojo/public/cpp/test_support/test_support.h
@@ -0,0 +1,34 @@
+// 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.
+
+#ifndef MOJO_PUBLIC_CPP_TEST_SUPPORT_TEST_SUPPORT_H_
+#define MOJO_PUBLIC_CPP_TEST_SUPPORT_TEST_SUPPORT_H_
+
+#include <string>
+#include <vector>
+
+#include "mojo/public/c/test_support/test_support.h"
+
+namespace mojo {
+namespace test {
+
+inline void LogPerfResult(const char* test_name,
+ double value,
+ const char* units) {
+ MojoTestSupportLogPerfResult(test_name, value, units);
+}
+
+// Opens text file relative to the source root for reading.
+inline FILE* OpenSourceRootRelativeFile(const std::string& relative_path) {
+ return MojoTestSupportOpenSourceRootRelativeFile(relative_path.c_str());
+}
+
+// Returns the list of regular files in a directory relative to the source root.
+std::vector<std::string> EnumerateSourceRootRelativeDirectory(
+ const std::string& relative_path);
+
+} // namespace test
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_TEST_SUPPORT_TEST_SUPPORT_H_
diff --git a/chromium/mojo/public/cpp/test_support/test_utils.h b/chromium/mojo/public/cpp/test_support/test_utils.h
new file mode 100644
index 00000000000..43a3ea99821
--- /dev/null
+++ b/chromium/mojo/public/cpp/test_support/test_utils.h
@@ -0,0 +1,39 @@
+// Copyright 2013 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.
+
+#ifndef MOJO_PUBLIC_CPP_TEST_SUPPORT_TEST_UTILS_H_
+#define MOJO_PUBLIC_CPP_TEST_SUPPORT_TEST_UTILS_H_
+
+#include <string>
+
+#include "mojo/public/cpp/system/core.h"
+
+namespace mojo {
+namespace test {
+
+// Writes a message to |handle| with message data |text|. Returns true on
+// success.
+bool WriteTextMessage(const MessagePipeHandle& handle, const std::string& text);
+
+// Reads a message from |handle|, putting its contents into |*text|. Returns
+// true on success. (This blocks if necessary and will call |MojoReadMessage()|
+// multiple times, e.g., to query the size of the message.)
+bool ReadTextMessage(const MessagePipeHandle& handle, std::string* text);
+
+// Discards a message from |handle|. Returns true on success. (This does not
+// block. It will fail if no message is available to discard.)
+bool DiscardMessage(const MessagePipeHandle& handle);
+
+// Run |single_iteration| an appropriate number of times and report its
+// performance appropriately. (This actually runs |single_iteration| for a fixed
+// amount of time and reports the number of iterations per unit time.)
+typedef void (*PerfTestSingleIteration)(void* closure);
+void IterateAndReportPerf(const char* test_name,
+ PerfTestSingleIteration single_iteration,
+ void* closure);
+
+} // namespace test
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_TEST_SUPPORT_TEST_UTILS_H_
diff --git a/chromium/mojo/public/cpp/utility/lib/mutex.cc b/chromium/mojo/public/cpp/utility/lib/mutex.cc
new file mode 100644
index 00000000000..23370e1c023
--- /dev/null
+++ b/chromium/mojo/public/cpp/utility/lib/mutex.cc
@@ -0,0 +1,52 @@
+// 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/public/cpp/utility/mutex.h"
+
+#include <assert.h>
+#include <errno.h>
+
+namespace mojo {
+
+// Release builds have inlined (non-error-checking) definitions in the header.
+#if !defined(NDEBUG)
+Mutex::Mutex() {
+ pthread_mutexattr_t mutexattr;
+ int rv = pthread_mutexattr_init(&mutexattr);
+ assert(rv == 0);
+ rv = pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_ERRORCHECK);
+ assert(rv == 0);
+ rv = pthread_mutex_init(&mutex_, &mutexattr);
+ assert(rv == 0);
+ rv = pthread_mutexattr_destroy(&mutexattr);
+ assert(rv == 0);
+}
+
+Mutex::~Mutex() {
+ int rv = pthread_mutex_destroy(&mutex_);
+ assert(rv == 0);
+}
+
+void Mutex::Lock() {
+ int rv = pthread_mutex_lock(&mutex_);
+ assert(rv == 0);
+}
+
+void Mutex::Unlock() {
+ int rv = pthread_mutex_unlock(&mutex_);
+ assert(rv == 0);
+}
+
+bool Mutex::TryLock() {
+ int rv = pthread_mutex_trylock(&mutex_);
+ assert(rv == 0 || rv == EBUSY);
+ return rv == 0;
+}
+
+void Mutex::AssertHeld() {
+ assert(pthread_mutex_lock(&mutex_) == EDEADLK);
+}
+#endif // !defined(NDEBUG)
+
+} // namespace mojo
diff --git a/chromium/mojo/public/cpp/utility/lib/run_loop.cc b/chromium/mojo/public/cpp/utility/lib/run_loop.cc
new file mode 100644
index 00000000000..f523eaeaead
--- /dev/null
+++ b/chromium/mojo/public/cpp/utility/lib/run_loop.cc
@@ -0,0 +1,221 @@
+// 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/public/cpp/utility/run_loop.h"
+
+#include <assert.h>
+
+#include <algorithm>
+#include <vector>
+
+#include "mojo/public/cpp/utility/lib/thread_local.h"
+#include "mojo/public/cpp/utility/run_loop_handler.h"
+
+namespace mojo {
+namespace {
+
+internal::ThreadLocalPointer<RunLoop> current_run_loop;
+
+const MojoTimeTicks kInvalidTimeTicks = static_cast<MojoTimeTicks>(0);
+
+} // namespace
+
+// State needed for one iteration of WaitMany().
+struct RunLoop::WaitState {
+ WaitState() : deadline(MOJO_DEADLINE_INDEFINITE) {}
+
+ std::vector<Handle> handles;
+ std::vector<MojoHandleSignals> handle_signals;
+ MojoDeadline deadline;
+};
+
+struct RunLoop::RunState {
+ RunState() : should_quit(false) {}
+
+ bool should_quit;
+};
+
+RunLoop::RunLoop() : run_state_(NULL), next_handler_id_(0) {
+ assert(!current());
+ current_run_loop.Set(this);
+}
+
+RunLoop::~RunLoop() {
+ assert(current() == this);
+ current_run_loop.Set(NULL);
+}
+
+// static
+void RunLoop::SetUp() {
+ current_run_loop.Allocate();
+}
+
+// static
+void RunLoop::TearDown() {
+ assert(!current());
+ current_run_loop.Free();
+}
+
+// static
+RunLoop* RunLoop::current() {
+ return current_run_loop.Get();
+}
+
+void RunLoop::AddHandler(RunLoopHandler* handler,
+ const Handle& handle,
+ MojoHandleSignals handle_signals,
+ MojoDeadline deadline) {
+ assert(current() == this);
+ assert(handler);
+ assert(handle.is_valid());
+ // Assume it's an error if someone tries to reregister an existing handle.
+ assert(0u == handler_data_.count(handle));
+ HandlerData handler_data;
+ handler_data.handler = handler;
+ handler_data.handle_signals = handle_signals;
+ handler_data.deadline = (deadline == MOJO_DEADLINE_INDEFINITE) ?
+ kInvalidTimeTicks :
+ GetTimeTicksNow() + static_cast<MojoTimeTicks>(deadline);
+ handler_data.id = next_handler_id_++;
+ handler_data_[handle] = handler_data;
+}
+
+void RunLoop::RemoveHandler(const Handle& handle) {
+ assert(current() == this);
+ handler_data_.erase(handle);
+}
+
+bool RunLoop::HasHandler(const Handle& handle) const {
+ return handler_data_.find(handle) != handler_data_.end();
+}
+
+void RunLoop::Run() {
+ assert(current() == this);
+ RunState* old_state = run_state_;
+ RunState run_state;
+ run_state_ = &run_state;
+ while (!run_state.should_quit)
+ Wait(false);
+ run_state_ = old_state;
+}
+
+void RunLoop::RunUntilIdle() {
+ assert(current() == this);
+ RunState* old_state = run_state_;
+ RunState run_state;
+ run_state_ = &run_state;
+ while (!run_state.should_quit) {
+ if (!Wait(true))
+ break;
+ }
+ run_state_ = old_state;
+}
+
+void RunLoop::Quit() {
+ assert(current() == this);
+ if (run_state_)
+ run_state_->should_quit = true;
+}
+
+bool RunLoop::Wait(bool non_blocking) {
+ const WaitState wait_state = GetWaitState(non_blocking);
+ if (wait_state.handles.empty()) {
+ Quit();
+ return false;
+ }
+
+ const MojoResult result = WaitMany(wait_state.handles,
+ wait_state.handle_signals,
+ wait_state.deadline);
+ if (result >= 0) {
+ const size_t index = static_cast<size_t>(result);
+ assert(handler_data_.find(wait_state.handles[index]) !=
+ handler_data_.end());
+ handler_data_[wait_state.handles[index]].handler->OnHandleReady(
+ wait_state.handles[index]);
+ return true;
+ }
+
+ switch (result) {
+ case MOJO_RESULT_INVALID_ARGUMENT:
+ case MOJO_RESULT_FAILED_PRECONDITION:
+ return RemoveFirstInvalidHandle(wait_state);
+ case MOJO_RESULT_DEADLINE_EXCEEDED:
+ return NotifyDeadlineExceeded();
+ }
+
+ assert(false);
+ return false;
+}
+
+bool RunLoop::NotifyDeadlineExceeded() {
+ bool notified = false;
+
+ // Make a copy in case someone tries to add/remove new handlers as part of
+ // notifying.
+ const HandleToHandlerData cloned_handlers(handler_data_);
+ const MojoTimeTicks now(GetTimeTicksNow());
+ for (HandleToHandlerData::const_iterator i = cloned_handlers.begin();
+ i != cloned_handlers.end(); ++i) {
+ // Since we're iterating over a clone of the handlers, verify the handler is
+ // still valid before notifying.
+ if (i->second.deadline != kInvalidTimeTicks &&
+ i->second.deadline < now &&
+ handler_data_.find(i->first) != handler_data_.end() &&
+ handler_data_[i->first].id == i->second.id) {
+ handler_data_.erase(i->first);
+ i->second.handler->OnHandleError(i->first, MOJO_RESULT_DEADLINE_EXCEEDED);
+ notified = true;
+ }
+ }
+
+ return notified;
+}
+
+bool RunLoop::RemoveFirstInvalidHandle(const WaitState& wait_state) {
+ for (size_t i = 0; i < wait_state.handles.size(); ++i) {
+ const MojoResult result =
+ mojo::Wait(wait_state.handles[i], wait_state.handle_signals[i],
+ static_cast<MojoDeadline>(0));
+ if (result == MOJO_RESULT_INVALID_ARGUMENT ||
+ result == MOJO_RESULT_FAILED_PRECONDITION) {
+ // Remove the handle first, this way if OnHandleError() tries to remove
+ // the handle our iterator isn't invalidated.
+ assert(handler_data_.find(wait_state.handles[i]) != handler_data_.end());
+ RunLoopHandler* handler =
+ handler_data_[wait_state.handles[i]].handler;
+ handler_data_.erase(wait_state.handles[i]);
+ handler->OnHandleError(wait_state.handles[i], result);
+ return true;
+ }
+ assert(MOJO_RESULT_DEADLINE_EXCEEDED == result);
+ }
+ return false;
+}
+
+RunLoop::WaitState RunLoop::GetWaitState(bool non_blocking) const {
+ WaitState wait_state;
+ MojoTimeTicks min_time = kInvalidTimeTicks;
+ for (HandleToHandlerData::const_iterator i = handler_data_.begin();
+ i != handler_data_.end(); ++i) {
+ wait_state.handles.push_back(i->first);
+ wait_state.handle_signals.push_back(i->second.handle_signals);
+ if (!non_blocking && i->second.deadline != kInvalidTimeTicks &&
+ (min_time == kInvalidTimeTicks || i->second.deadline < min_time)) {
+ min_time = i->second.deadline;
+ }
+ }
+ if (non_blocking) {
+ wait_state.deadline = static_cast<MojoDeadline>(0);
+ } else if (min_time != kInvalidTimeTicks) {
+ const MojoTimeTicks now = GetTimeTicksNow();
+ if (min_time < now)
+ wait_state.deadline = static_cast<MojoDeadline>(0);
+ else
+ wait_state.deadline = static_cast<MojoDeadline>(min_time - now);
+ }
+ return wait_state;
+}
+
+} // namespace mojo
diff --git a/chromium/mojo/public/cpp/utility/lib/thread.cc b/chromium/mojo/public/cpp/utility/lib/thread.cc
new file mode 100644
index 00000000000..da33497df42
--- /dev/null
+++ b/chromium/mojo/public/cpp/utility/lib/thread.cc
@@ -0,0 +1,69 @@
+// 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/public/cpp/utility/thread.h"
+
+#include <assert.h>
+
+namespace mojo {
+
+Thread::Thread()
+ : options_(),
+ thread_(),
+ started_(false),
+ joined_(false) {
+}
+
+Thread::Thread(const Options& options)
+ : options_(options),
+ thread_(),
+ started_(false),
+ joined_(false) {
+}
+
+Thread::~Thread() {
+ // If it was started, it must have been joined.
+ assert(!started_ || joined_);
+}
+
+void Thread::Start() {
+ assert(!started_);
+ assert(!joined_);
+
+ pthread_attr_t attr;
+ int rv MOJO_ALLOW_UNUSED = pthread_attr_init(&attr);
+ assert(rv == 0);
+
+ // Non-default stack size?
+ if (options_.stack_size() != 0) {
+ rv = pthread_attr_setstacksize(&attr, options_.stack_size());
+ assert(rv == 0);
+ }
+
+ started_ = true;
+ rv = pthread_create(&thread_, &attr, &ThreadRunTrampoline, this);
+ assert(rv == 0);
+
+ rv = pthread_attr_destroy(&attr);
+ assert(rv == 0);
+}
+
+void Thread::Join() {
+ // Must have been started but not yet joined.
+ assert(started_);
+ assert(!joined_);
+
+ joined_ = true;
+ int rv MOJO_ALLOW_UNUSED = pthread_join(thread_, NULL);
+ assert(rv == 0);
+}
+
+// static
+void* Thread::ThreadRunTrampoline(void* arg) {
+ Thread* self = static_cast<Thread*>(arg);
+ self->Run();
+ return NULL;
+}
+
+} // namespace mojo
diff --git a/chromium/mojo/public/cpp/utility/lib/thread_local.h b/chromium/mojo/public/cpp/utility/lib/thread_local.h
new file mode 100644
index 00000000000..4c3625d00d8
--- /dev/null
+++ b/chromium/mojo/public/cpp/utility/lib/thread_local.h
@@ -0,0 +1,61 @@
+// 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.
+
+#ifndef MOJO_PUBLIC_CPP_UTILITY_LIB_THREAD_LOCAL_H_
+#define MOJO_PUBLIC_CPP_UTILITY_LIB_THREAD_LOCAL_H_
+
+#ifndef _WIN32
+#include <pthread.h>
+#endif
+
+#include "mojo/public/cpp/system/macros.h"
+
+namespace mojo {
+namespace internal {
+
+// Helper functions that abstract the cross-platform APIs.
+struct ThreadLocalPlatform {
+#ifdef _WIN32
+ typedef unsigned long SlotType;
+#else
+ typedef pthread_key_t SlotType;
+#endif
+
+ static void AllocateSlot(SlotType* slot);
+ static void FreeSlot(SlotType slot);
+ static void* GetValueFromSlot(SlotType slot);
+ static void SetValueInSlot(SlotType slot, void* value);
+};
+
+// This class is intended to be statically allocated.
+template <typename P>
+class ThreadLocalPointer {
+ public:
+ ThreadLocalPointer() : slot_() {
+ }
+
+ void Allocate() {
+ ThreadLocalPlatform::AllocateSlot(&slot_);
+ }
+
+ void Free() {
+ ThreadLocalPlatform::FreeSlot(slot_);
+ }
+
+ P* Get() {
+ return static_cast<P*>(ThreadLocalPlatform::GetValueFromSlot(slot_));
+ }
+
+ void Set(P* value) {
+ ThreadLocalPlatform::SetValueInSlot(slot_, value);
+ }
+
+ private:
+ ThreadLocalPlatform::SlotType slot_;
+};
+
+} // namespace internal
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_UTILITY_LIB_THREAD_LOCAL_H_
diff --git a/chromium/mojo/public/cpp/utility/lib/thread_local_posix.cc b/chromium/mojo/public/cpp/utility/lib/thread_local_posix.cc
new file mode 100644
index 00000000000..b33dfc61297
--- /dev/null
+++ b/chromium/mojo/public/cpp/utility/lib/thread_local_posix.cc
@@ -0,0 +1,39 @@
+// 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/public/cpp/utility/lib/thread_local.h"
+
+#include <assert.h>
+
+namespace mojo {
+namespace internal {
+
+// static
+void ThreadLocalPlatform::AllocateSlot(SlotType* slot) {
+ if (pthread_key_create(slot, NULL) != 0) {
+ assert(false);
+ }
+}
+
+// static
+void ThreadLocalPlatform::FreeSlot(SlotType slot) {
+ if (pthread_key_delete(slot) != 0) {
+ assert(false);
+ }
+}
+
+// static
+void* ThreadLocalPlatform::GetValueFromSlot(SlotType slot) {
+ return pthread_getspecific(slot);
+}
+
+// static
+void ThreadLocalPlatform::SetValueInSlot(SlotType slot, void* value) {
+ if (pthread_setspecific(slot, value) != 0) {
+ assert(false);
+ }
+}
+
+} // namespace internal
+} // namespace mojo
diff --git a/chromium/mojo/public/cpp/utility/lib/thread_local_win.cc b/chromium/mojo/public/cpp/utility/lib/thread_local_win.cc
new file mode 100644
index 00000000000..98841f7273a
--- /dev/null
+++ b/chromium/mojo/public/cpp/utility/lib/thread_local_win.cc
@@ -0,0 +1,39 @@
+// 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/public/cpp/utility/lib/thread_local.h"
+
+#include <assert.h>
+#include <windows.h>
+
+namespace mojo {
+namespace internal {
+
+// static
+void ThreadLocalPlatform::AllocateSlot(SlotType* slot) {
+ *slot = TlsAlloc();
+ assert(*slot != TLS_OUT_OF_INDEXES);
+}
+
+// static
+void ThreadLocalPlatform::FreeSlot(SlotType slot) {
+ if (!TlsFree(slot)) {
+ assert(false);
+ }
+}
+
+// static
+void* ThreadLocalPlatform::GetValueFromSlot(SlotType slot) {
+ return TlsGetValue(slot);
+}
+
+// static
+void ThreadLocalPlatform::SetValueInSlot(SlotType slot, void* value) {
+ if (!TlsSetValue(slot, value)) {
+ assert(false);
+ }
+}
+
+} // namespace internal
+} // namespace mojo
diff --git a/chromium/mojo/public/cpp/utility/mutex.h b/chromium/mojo/public/cpp/utility/mutex.h
new file mode 100644
index 00000000000..35611c2ba9a
--- /dev/null
+++ b/chromium/mojo/public/cpp/utility/mutex.h
@@ -0,0 +1,70 @@
+// 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.
+
+#ifndef MOJO_PUBLIC_CPP_UTILITY_MUTEX_H_
+#define MOJO_PUBLIC_CPP_UTILITY_MUTEX_H_
+
+#ifdef _WIN32
+#error "Not implemented: See crbug.com/342893."
+#endif
+
+#include <pthread.h>
+
+#include "mojo/public/cpp/system/macros.h"
+
+namespace mojo {
+
+#ifdef NDEBUG
+// Note: Make a C++ constant for |PTHREAD_MUTEX_INITIALIZER|. (We can't directly
+// use the C macro in an initializer list, since it might expand to |{ ... }|.)
+namespace internal {
+const pthread_mutex_t kPthreadMutexInitializer = PTHREAD_MUTEX_INITIALIZER;
+}
+#endif
+
+class Mutex {
+ public:
+#ifdef NDEBUG
+ Mutex() : mutex_(internal::kPthreadMutexInitializer) {}
+ ~Mutex() { pthread_mutex_destroy(&mutex_); }
+
+ void Lock() { pthread_mutex_lock(&mutex_); }
+ void Unlock() { pthread_mutex_unlock(&mutex_); }
+ bool TryLock() { return pthread_mutex_trylock(&mutex_) == 0; }
+
+ void AssertHeld() {}
+#else
+ Mutex();
+ ~Mutex();
+
+ void Lock();
+ void Unlock();
+ bool TryLock();
+
+ void AssertHeld();
+#endif
+
+ private:
+ pthread_mutex_t mutex_;
+
+ MOJO_DISALLOW_COPY_AND_ASSIGN(Mutex);
+};
+
+class MutexLock {
+ public:
+ explicit MutexLock(Mutex* mutex) : mutex_(mutex) { mutex_->Lock(); }
+ ~MutexLock() { mutex_->Unlock(); }
+
+ private:
+ Mutex* const mutex_;
+
+ MOJO_DISALLOW_COPY_AND_ASSIGN(MutexLock);
+};
+
+// Catch bug where variable name is omitted (e.g., |MutexLock (&mu)|).
+#define MutexLock(x) MOJO_COMPILE_ASSERT(0, mutex_lock_missing_variable_name);
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_UTILITY_MUTEX_H_
diff --git a/chromium/mojo/public/cpp/utility/run_loop.h b/chromium/mojo/public/cpp/utility/run_loop.h
new file mode 100644
index 00000000000..74f870abc57
--- /dev/null
+++ b/chromium/mojo/public/cpp/utility/run_loop.h
@@ -0,0 +1,108 @@
+// Copyright 2013 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.
+
+#ifndef MOJO_PUBLIC_CPP_UTILITY_RUN_LOOP_H_
+#define MOJO_PUBLIC_CPP_UTILITY_RUN_LOOP_H_
+
+#include <map>
+
+#include "mojo/public/cpp/system/core.h"
+
+namespace mojo {
+
+class RunLoopHandler;
+
+class RunLoop {
+ public:
+ RunLoop();
+ ~RunLoop();
+
+ // Sets up state needed for RunLoop. This must be invoked before creating a
+ // RunLoop.
+ static void SetUp();
+
+ // Cleans state created by Setup().
+ static void TearDown();
+
+ // Returns the RunLoop for the current thread. Returns NULL if not yet
+ // created.
+ static RunLoop* current();
+
+ // Registers a RunLoopHandler for the specified handle. Only one handler can
+ // be registered for a specified handle.
+ void AddHandler(RunLoopHandler* handler,
+ const Handle& handle,
+ MojoHandleSignals handle_signals,
+ MojoDeadline deadline);
+ void RemoveHandler(const Handle& handle);
+ bool HasHandler(const Handle& handle) const;
+
+ // Runs the loop servicing handles as they are ready. This returns when Quit()
+ // is invoked, or there no more handles.
+ void Run();
+
+ // Runs the loop servicing any handles that are ready. Does not wait for
+ // handles to become ready before returning. Returns early if Quit() is
+ // invoked.
+ void RunUntilIdle();
+
+ void Quit();
+
+ private:
+ struct RunState;
+ struct WaitState;
+
+ // Contains the data needed to track a request to AddHandler().
+ struct HandlerData {
+ HandlerData()
+ : handler(NULL),
+ handle_signals(MOJO_HANDLE_SIGNAL_NONE),
+ deadline(0),
+ id(0) {}
+
+ RunLoopHandler* handler;
+ MojoHandleSignals handle_signals;
+ MojoTimeTicks deadline;
+ // See description of |RunLoop::next_handler_id_| for details.
+ int id;
+ };
+
+ typedef std::map<Handle, HandlerData> HandleToHandlerData;
+
+ // Waits for a handle to be ready. Returns after servicing at least one
+ // handle (or there are no more handles) unless |non_blocking| is true,
+ // in which case it will also return if servicing at least one handle
+ // would require blocking. Returns true if a RunLoopHandler was notified.
+ bool Wait(bool non_blocking);
+
+ // Notifies any handlers whose deadline has expired. Returns true if a
+ // RunLoopHandler was notified.
+ bool NotifyDeadlineExceeded();
+
+ // Removes the first invalid handle. This is called if MojoWaitMany() finds an
+ // invalid handle. Returns true if a RunLoopHandler was notified.
+ bool RemoveFirstInvalidHandle(const WaitState& wait_state);
+
+ // Returns the state needed to pass to WaitMany().
+ WaitState GetWaitState(bool non_blocking) const;
+
+ HandleToHandlerData handler_data_;
+
+ // If non-NULL we're running (inside Run()). Member references a value on the
+ // stack.
+ RunState* run_state_;
+
+ // An ever increasing value assigned to each HandlerData::id. Used to detect
+ // uniqueness while notifying. That is, while notifying expired timers we copy
+ // |handler_data_| and only notify handlers whose id match. If the id does not
+ // match it means the handler was removed then added so that we shouldn't
+ // notify it.
+ int next_handler_id_;
+
+ MOJO_DISALLOW_COPY_AND_ASSIGN(RunLoop);
+};
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_UTILITY_RUN_LOOP_H_
diff --git a/chromium/mojo/public/cpp/utility/run_loop_handler.h b/chromium/mojo/public/cpp/utility/run_loop_handler.h
new file mode 100644
index 00000000000..69838d5e57c
--- /dev/null
+++ b/chromium/mojo/public/cpp/utility/run_loop_handler.h
@@ -0,0 +1,25 @@
+// Copyright 2013 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.
+
+#ifndef MOJO_PUBLIC_CPP_UTILITY_RUN_LOOP_HANDLER_H_
+#define MOJO_PUBLIC_CPP_UTILITY_RUN_LOOP_HANDLER_H_
+
+#include "mojo/public/cpp/system/core.h"
+
+namespace mojo {
+
+// Used by RunLoop to notify when a handle is either ready or has become
+// invalid.
+class RunLoopHandler {
+ public:
+ virtual void OnHandleReady(const Handle& handle) = 0;
+ virtual void OnHandleError(const Handle& handle, MojoResult result) = 0;
+
+ protected:
+ virtual ~RunLoopHandler() {}
+};
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_UTILITY_RUN_LOOP_HANDLER_H_
diff --git a/chromium/mojo/public/cpp/utility/thread.h b/chromium/mojo/public/cpp/utility/thread.h
new file mode 100644
index 00000000000..b7d10ee7037
--- /dev/null
+++ b/chromium/mojo/public/cpp/utility/thread.h
@@ -0,0 +1,62 @@
+// 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.
+
+#ifndef MOJO_PUBLIC_CPP_UTILITY_THREAD_H_
+#define MOJO_PUBLIC_CPP_UTILITY_THREAD_H_
+
+#ifdef _WIN32
+#error "Not implemented: See crbug.com/342893."
+#endif
+
+#include <pthread.h>
+#include <stddef.h>
+
+#include "mojo/public/cpp/system/macros.h"
+
+namespace mojo {
+
+// This class is thread-friendly, not thread-safe (e.g., you mustn't call
+// |Join()| from multiple threads and/or simultaneously try to destroy the
+// object).
+class Thread {
+ public:
+ // TODO(vtl): Support non-joinable? priority?
+ class Options {
+ public:
+ Options() : stack_size_(0) {}
+
+ // A stack size of 0 means the default.
+ size_t stack_size() const { return stack_size_; }
+ void set_stack_size(size_t stack_size) { stack_size_ = stack_size; }
+
+ private:
+ size_t stack_size_;
+
+ // Copy and assign allowed.
+ };
+
+ // TODO(vtl): Add name or name prefix?
+ Thread();
+ explicit Thread(const Options& options);
+ virtual ~Thread();
+
+ void Start();
+ void Join();
+
+ virtual void Run() = 0;
+
+ private:
+ static void* ThreadRunTrampoline(void* arg);
+
+ const Options options_;
+ pthread_t thread_;
+ bool started_;
+ bool joined_;
+
+ MOJO_DISALLOW_COPY_AND_ASSIGN(Thread);
+};
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_UTILITY_THREAD_H_