diff options
author | jamesr <jamesr@chromium.org> | 2014-11-18 17:35:28 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-11-19 01:35:49 +0000 |
commit | a9125266d3fc89ff0bfd4c3a05bf2f31ffaeff1f (patch) | |
tree | 954602a17f1bfd7fd9d10c255360f75a6ada0d28 /mojo/edk/embedder | |
parent | 558999147d4fdfd1ae7ee79cfa1c6599eab47d57 (diff) | |
download | chromium_src-a9125266d3fc89ff0bfd4c3a05bf2f31ffaeff1f.zip chromium_src-a9125266d3fc89ff0bfd4c3a05bf2f31ffaeff1f.tar.gz chromium_src-a9125266d3fc89ff0bfd4c3a05bf2f31ffaeff1f.tar.bz2 |
Update mojo sdk to rev e01f9a49449381a5eb430c1fd88bf2cae73ec35a
Includes updates to ipc/mojo/ipc_channel_mojo.cc for mojo::embedder API
changes and updates to use mojo::Binding<> in ui/keyboard and
device/battery.
Review URL: https://codereview.chromium.org/728133002
Cr-Commit-Position: refs/heads/master@{#304731}
Diffstat (limited to 'mojo/edk/embedder')
20 files changed, 547 insertions, 385 deletions
diff --git a/mojo/edk/embedder/BUILD.gn b/mojo/edk/embedder/BUILD.gn index 50e93b0..3bd9df0 100644 --- a/mojo/edk/embedder/BUILD.gn +++ b/mojo/edk/embedder/BUILD.gn @@ -3,11 +3,26 @@ # found in the LICENSE file. source_set("embedder") { - # This isn't really a standalone target, it must be linked into the + # This isn't really a standalone target; it must be linked into the # mojo_system_impl component. visibility = [ "//mojo/edk/system" ] - deps = [ "//base", ] + sources = [ + "channel_info_forward.h", + "channel_init.cc", + "channel_init.h", + "configuration.h", + "embedder.cc", + "embedder.h", + "embedder_internal.h", + "entrypoints.cc", + # Test-only code: + # TODO(vtl): It's a little unfortunate that these end up in the same + # component as non-test-only code. In the static build, this code should + # hopefully be dead-stripped. + "test_embedder.cc", + "test_embedder.h", + ] defines = [ "MOJO_SYSTEM_IMPL_IMPLEMENTATION", @@ -16,12 +31,23 @@ source_set("embedder") { configs += [ "//mojo/edk/system:system_config" ] + public_deps = [ + ":platform", + "//mojo/public/cpp/system", + ] + + deps = [ "//base" ] +} + +source_set("platform") { + # This isn't really a standalone target; it must be linked into the + # mojo_system_impl component. + visibility = [ + ":embedder", + "//mojo/edk/system", + ] + sources = [ - "channel_info_forward.h", - "channel_init.cc", - "channel_init.h", - "embedder.cc", - "embedder.h", "platform_channel_pair.cc", "platform_channel_pair.h", "platform_channel_pair_posix.cc", @@ -43,30 +69,30 @@ source_set("embedder") { "simple_platform_shared_buffer_win.cc", "simple_platform_support.cc", "simple_platform_support.h", - # Test-only code: - # TODO(vtl): It's a little unfortunate that these end up in the same - # component as non-test-only code. In the static build, this code should - # hopefully be dead-stripped. - "test_embedder.cc", - "test_embedder.h", ] + + defines = [ "MOJO_SYSTEM_IMPL_IMPLEMENTATION" ] + + configs += [ "//mojo/edk/system:system_config" ] + + deps = [ "//base" ] } source_set("embedder_unittests") { testonly = true visibility = [ "//mojo/edk/system:mojo_system_unittests" ] - testonly = true + + sources = [ + "embedder_unittest.cc", + "platform_channel_pair_posix_unittest.cc", + "simple_platform_shared_buffer_unittest.cc", + ] deps = [ "//base", + "//base/test:test_support", "//mojo/edk/test:test_support", "//mojo/edk/system", "//testing/gtest", ] - - sources = [ - "embedder_unittest.cc", - "platform_channel_pair_posix_unittest.cc", - "simple_platform_shared_buffer_unittest.cc", - ] } diff --git a/mojo/edk/embedder/channel_info_forward.h b/mojo/edk/embedder/channel_info_forward.h index 494d5ef..8d23836 100644 --- a/mojo/edk/embedder/channel_info_forward.h +++ b/mojo/edk/embedder/channel_info_forward.h @@ -9,23 +9,14 @@ #define MOJO_EDK_EMBEDDER_CHANNEL_INFO_FORWARD_H_ namespace mojo { - -// Forward declare |system::ChannelInfo|, so that we can typedef it to -// |embedder::ChannelInfo|. Users of the embedder API shouldn't use this -// directly; instead they should use |embedder::ChannelInfo|. -namespace system { -struct ChannelInfo; -} - namespace embedder { // This is an opaque type. The embedder API uses (returns and takes as // arguments) pointers to this type. (We don't simply use |void*|, so that // custom deleters and such can be used without additional wrappers. -typedef system::ChannelInfo ChannelInfo; +struct ChannelInfo; } // namespace embedder - } // namespace mojo #endif // MOJO_EDK_EMBEDDER_CHANNEL_INFO_FORWARD_H_ diff --git a/mojo/edk/embedder/channel_init.cc b/mojo/edk/embedder/channel_init.cc index 9ea984b..0e7a7b6 100644 --- a/mojo/edk/embedder/channel_init.cc +++ b/mojo/edk/embedder/channel_init.cc @@ -25,12 +25,11 @@ ScopedMessagePipeHandle ChannelInit::Init( DCHECK(!io_thread_task_runner_.get()); // Should only init once. io_thread_task_runner_ = io_thread_task_runner; ScopedMessagePipeHandle message_pipe = - CreateChannel(ScopedPlatformHandle(PlatformHandle(file)), - io_thread_task_runner, - base::Bind(&ChannelInit::OnCreatedChannel, - weak_factory_.GetWeakPtr(), - io_thread_task_runner), - base::MessageLoop::current()->message_loop_proxy()).Pass(); + CreateChannel( + ScopedPlatformHandle(PlatformHandle(file)), io_thread_task_runner, + base::Bind(&ChannelInit::OnCreatedChannel, weak_factory_.GetWeakPtr(), + io_thread_task_runner), + base::MessageLoop::current()->message_loop_proxy()).Pass(); return message_pipe.Pass(); } diff --git a/mojo/edk/embedder/channel_init.h b/mojo/edk/embedder/channel_init.h index ce191b4..59b6694 100644 --- a/mojo/edk/embedder/channel_init.h +++ b/mojo/edk/embedder/channel_init.h @@ -10,7 +10,7 @@ #include "base/memory/weak_ptr.h" #include "mojo/edk/embedder/channel_info_forward.h" #include "mojo/edk/system/system_impl_export.h" -#include "mojo/public/cpp/system/core.h" +#include "mojo/public/cpp/system/message_pipe.h" namespace base { class MessageLoopProxy; diff --git a/mojo/edk/embedder/configuration.h b/mojo/edk/embedder/configuration.h new file mode 100644 index 0000000..0f99e1f --- /dev/null +++ b/mojo/edk/embedder/configuration.h @@ -0,0 +1,68 @@ +// 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_EDK_EMBEDDER_CONFIGURATION_H_ +#define MOJO_EDK_EMBEDDER_CONFIGURATION_H_ + +#include <stddef.h> + +namespace mojo { +namespace embedder { + +// A set of constants that the Mojo system internally uses. These values should +// be consistent across all processes on the same system. +// +// In general, there should be no need to change these values from their +// defaults. However, if you do change them, you must do so before +// initialization. +struct Configuration { + // Maximum number of open (Mojo) handles. The default is 1,000,000. + // + // TODO(vtl): This doesn't count "live" handles, some of which may live in + // messages. + size_t max_handle_table_size; + + // Maximum number of active memory mappings. The default is 1,000,000. + size_t max_mapping_table_sze; + + // Upper limit of |MojoWaitMany()|'s |num_handles|. The default is 1,000,000. + // Must be same as or smaller than |max_handle_table_size|. + size_t max_wait_many_num_handles; + + // Maximum data size of messages sent over message pipes, in bytes. The + // default is 4MB. + size_t max_message_num_bytes; + + // Maximum number of handles that can be attached to messages sent over + // message pipes. The default is 10,000. + size_t max_message_num_handles; + + // Maximum capacity of a data pipe, in bytes. The default is 256MB. This value + // must fit into a |uint32_t|. WARNING: If you bump it closer to 2^32, you + // must audit all the code to check that we don't overflow (2^31 would + // definitely be risky; up to 2^30 is probably okay). + size_t max_data_pipe_capacity_bytes; + + // Default data pipe capacity, if not specified explicitly in the creation + // options. The default is 1MB. + size_t default_data_pipe_capacity_bytes; + + // Alignment for the "start" of the data buffer used by data pipes. (The + // alignment of elements will depend on this and the element size.) The + // default is 16 bytes. + size_t data_pipe_buffer_alignment_bytes; + + // Maximum size of a single shared memory segment, in bytes. The default is + // 1GB. + // + // TODO(vtl): Set this hard limit appropriately (e.g., higher on 64-bit). + // (This will also entail some auditing to make sure I'm not messing up my + // checks anywhere.) + size_t max_shared_memory_num_bytes; +}; + +} // namespace embedder +} // namespace mojo + +#endif // MOJO_EDK_EMBEDDER_CONFIGURATION_H_ diff --git a/mojo/edk/embedder/embedder.cc b/mojo/edk/embedder/embedder.cc index ca2169a..9c73eb0 100644 --- a/mojo/edk/embedder/embedder.cc +++ b/mojo/edk/embedder/embedder.cc @@ -9,12 +9,13 @@ #include "base/logging.h" #include "base/memory/scoped_ptr.h" #include "base/message_loop/message_loop_proxy.h" +#include "mojo/edk/embedder/embedder_internal.h" #include "mojo/edk/embedder/platform_support.h" #include "mojo/edk/system/channel.h" #include "mojo/edk/system/channel_endpoint.h" -#include "mojo/edk/system/channel_info.h" +#include "mojo/edk/system/channel_manager.h" +#include "mojo/edk/system/configuration.h" #include "mojo/edk/system/core.h" -#include "mojo/edk/system/entrypoints.h" #include "mojo/edk/system/message_pipe_dispatcher.h" #include "mojo/edk/system/platform_handle_dispatcher.h" #include "mojo/edk/system/raw_channel.h" @@ -24,39 +25,41 @@ namespace embedder { namespace { -// Helper for |CreateChannel...()|. (Note: May return null for some failures.) -scoped_refptr<system::Channel> MakeChannel( - system::Core* core, +// Helper for |CreateChannel...()|. Returns 0 on failure. Called on the channel +// creation thread. +system::ChannelId MakeChannel( ScopedPlatformHandle platform_handle, scoped_refptr<system::ChannelEndpoint> channel_endpoint) { DCHECK(platform_handle.is_valid()); // Create and initialize a |system::Channel|. + DCHECK(internal::g_core); scoped_refptr<system::Channel> channel = - new system::Channel(core->platform_support()); + new system::Channel(internal::g_core->platform_support()); if (!channel->Init(system::RawChannel::Create(platform_handle.Pass()))) { // This is very unusual (e.g., maybe |platform_handle| was invalid or we // reached some system resource limit). LOG(ERROR) << "Channel::Init() failed"; // Return null, since |Shutdown()| shouldn't be called in this case. - return scoped_refptr<system::Channel>(); + return 0; } - // Once |Init()| has succeeded, we have to return |channel| (since - // |Shutdown()| will have to be called on it). channel->AttachAndRunEndpoint(channel_endpoint, true); - return channel; + + DCHECK(internal::g_channel_manager); + return internal::g_channel_manager->AddChannel( + channel, base::MessageLoopProxy::current()); } +// Helper for |CreateChannel()|. Called on the channel creation thread. void CreateChannelHelper( - system::Core* core, ScopedPlatformHandle platform_handle, scoped_ptr<ChannelInfo> channel_info, scoped_refptr<system::ChannelEndpoint> channel_endpoint, DidCreateChannelCallback callback, scoped_refptr<base::TaskRunner> callback_thread_task_runner) { - channel_info->channel = - MakeChannel(core, platform_handle.Pass(), channel_endpoint); + channel_info->channel_id = + MakeChannel(platform_handle.Pass(), channel_endpoint); // Hand the channel back to the embedder. if (callback_thread_task_runner.get()) { @@ -69,8 +72,23 @@ void CreateChannelHelper( } // namespace +namespace internal { + +// Declared in embedder_internal.h. +system::Core* g_core = nullptr; +system::ChannelManager* g_channel_manager = nullptr; + +} // namespace internal + void Init(scoped_ptr<PlatformSupport> platform_support) { - system::entrypoints::SetCore(new system::Core(platform_support.Pass())); + DCHECK(!internal::g_core); + internal::g_core = new system::Core(platform_support.Pass()); + DCHECK(!internal::g_channel_manager); + internal::g_channel_manager = new system::ChannelManager(); +} + +Configuration* GetConfiguration() { + return system::GetMutableConfiguration(); } // TODO(vtl): Write tests for this. @@ -84,14 +102,12 @@ ScopedMessagePipeHandle CreateChannelOnIOThread( scoped_refptr<system::MessagePipeDispatcher> dispatcher = system::MessagePipeDispatcher::CreateRemoteMessagePipe(&channel_endpoint); - system::Core* core = system::entrypoints::GetCore(); - DCHECK(core); + DCHECK(internal::g_core); ScopedMessagePipeHandle rv( - MessagePipeHandle(core->AddDispatcher(dispatcher))); + MessagePipeHandle(internal::g_core->AddDispatcher(dispatcher))); - *channel_info = new ChannelInfo( - MakeChannel(core, platform_handle.Pass(), channel_endpoint), - base::MessageLoopProxy::current()); + *channel_info = + new ChannelInfo(MakeChannel(platform_handle.Pass(), channel_endpoint)); return rv.Pass(); } @@ -109,24 +125,19 @@ ScopedMessagePipeHandle CreateChannel( scoped_refptr<system::MessagePipeDispatcher> dispatcher = system::MessagePipeDispatcher::CreateRemoteMessagePipe(&channel_endpoint); - system::Core* core = system::entrypoints::GetCore(); - DCHECK(core); + DCHECK(internal::g_core); ScopedMessagePipeHandle rv( - MessagePipeHandle(core->AddDispatcher(dispatcher))); + MessagePipeHandle(internal::g_core->AddDispatcher(dispatcher))); + // We'll have to set |channel_info->channel_id| on the I/O thread. scoped_ptr<ChannelInfo> channel_info(new ChannelInfo()); - // We'll have to set |channel_info->channel| on the I/O thread. - channel_info->channel_thread_task_runner = io_thread_task_runner; if (rv.is_valid()) { - io_thread_task_runner->PostTask(FROM_HERE, - base::Bind(&CreateChannelHelper, - base::Unretained(core), - base::Passed(&platform_handle), - base::Passed(&channel_info), - channel_endpoint, - callback, - callback_thread_task_runner)); + io_thread_task_runner->PostTask( + FROM_HERE, + base::Bind(&CreateChannelHelper, base::Passed(&platform_handle), + base::Passed(&channel_info), channel_endpoint, callback, + callback_thread_task_runner)); } else { (callback_thread_task_runner.get() ? callback_thread_task_runner : io_thread_task_runner) @@ -136,35 +147,25 @@ ScopedMessagePipeHandle CreateChannel( return rv.Pass(); } -void DestroyChannelOnIOThread(ChannelInfo* channel_info) { - DCHECK(channel_info); - if (!channel_info->channel.get()) { - // Presumably, |Init()| on the channel failed. - return; - } - - channel_info->channel->Shutdown(); - delete channel_info; -} - // TODO(vtl): Write tests for this. void DestroyChannel(ChannelInfo* channel_info) { DCHECK(channel_info); - DCHECK(channel_info->channel_thread_task_runner.get()); - - if (!channel_info->channel.get()) { + if (!channel_info->channel_id) { // Presumably, |Init()| on the channel failed. return; } - channel_info->channel->WillShutdownSoon(); - channel_info->channel_thread_task_runner->PostTask( - FROM_HERE, base::Bind(&DestroyChannelOnIOThread, channel_info)); + DCHECK(internal::g_channel_manager); + // This will destroy the channel synchronously if called from the channel + // thread. + internal::g_channel_manager->ShutdownChannel(channel_info->channel_id); + delete channel_info; } void WillDestroyChannelSoon(ChannelInfo* channel_info) { DCHECK(channel_info); - channel_info->channel->WillShutdownSoon(); + DCHECK(internal::g_channel_manager); + internal::g_channel_manager->WillShutdownChannel(channel_info->channel_id); } MojoResult CreatePlatformHandleWrapper( @@ -175,9 +176,8 @@ MojoResult CreatePlatformHandleWrapper( scoped_refptr<system::Dispatcher> dispatcher( new system::PlatformHandleDispatcher(platform_handle.Pass())); - system::Core* core = system::entrypoints::GetCore(); - DCHECK(core); - MojoHandle h = core->AddDispatcher(dispatcher); + DCHECK(internal::g_core); + MojoHandle h = internal::g_core->AddDispatcher(dispatcher); if (h == MOJO_HANDLE_INVALID) { LOG(ERROR) << "Handle table full"; dispatcher->Close(); @@ -192,10 +192,9 @@ MojoResult PassWrappedPlatformHandle(MojoHandle platform_handle_wrapper_handle, ScopedPlatformHandle* platform_handle) { DCHECK(platform_handle); - system::Core* core = system::entrypoints::GetCore(); - DCHECK(core); + DCHECK(internal::g_core); scoped_refptr<system::Dispatcher> dispatcher( - core->GetDispatcher(platform_handle_wrapper_handle)); + internal::g_core->GetDispatcher(platform_handle_wrapper_handle)); if (!dispatcher.get()) return MOJO_RESULT_INVALID_ARGUMENT; diff --git a/mojo/edk/embedder/embedder.h b/mojo/edk/embedder/embedder.h index 85bc5832..02b4ac3 100644 --- a/mojo/edk/embedder/embedder.h +++ b/mojo/edk/embedder/embedder.h @@ -12,23 +12,32 @@ #include "mojo/edk/embedder/channel_info_forward.h" #include "mojo/edk/embedder/scoped_platform_handle.h" #include "mojo/edk/system/system_impl_export.h" -#include "mojo/public/cpp/system/core.h" +#include "mojo/public/cpp/system/message_pipe.h" namespace mojo { namespace embedder { +struct Configuration; class PlatformSupport; -// Must be called first to initialize the (global, singleton) system. +// Must be called first, or just after setting configuration parameters, +// to initialize the (global, singleton) system. MOJO_SYSTEM_IMPL_EXPORT void Init(scoped_ptr<PlatformSupport> platform_support); +// Returns the global configuration. In general there should be no need to +// change the configuration, but if you do so this must be done before calling +// |Init()|. +MOJO_SYSTEM_IMPL_EXPORT Configuration* GetConfiguration(); + // A "channel" is a connection on top of an OS "pipe", on top of which Mojo // message pipes (etc.) can be multiplexed. It must "live" on some I/O thread. // -// There are two "channel" creation/destruction APIs: the synchronous -// |CreateChannelOnIOThread()|/|DestroyChannelOnIOThread()|, which must be -// called from the I/O thread, and the asynchronous -// |CreateChannel()|/|DestroyChannel()|, which may be called from any thread. +// There are two channel creation APIs: |CreateChannelOnIOThread()| creates a +// channel synchronously and must be called from the I/O thread, while +// |CreateChannel()| is asynchronous and may be called from any thread. +// |DestroyChannel()| is used to destroy the channel in either case and may be +// called from any thread, but completes synchronously when called from the I/O +// thread. // // Both creation functions have a |platform_handle| argument, which should be an // OS-dependent handle to one side of a suitable bidirectional OS "pipe" (e.g., @@ -60,44 +69,37 @@ MOJO_SYSTEM_IMPL_EXPORT void Init(scoped_ptr<PlatformSupport> platform_support); // Creates a channel; must only be called from the I/O thread. |platform_handle| // should be a handle to a connected OS "pipe". Eventually (even on failure), -// the "out" value |*channel_info| should be passed to -// |DestroyChannelOnIOThread()| (or |DestoryChannel()|) to tear down the -// channel. Returns a handle to the bootstrap message pipe. +// the "out" value |*channel_info| should be passed to |DestoryChannel()| to +// tear down the channel. Returns a handle to the bootstrap message pipe. MOJO_SYSTEM_IMPL_EXPORT ScopedMessagePipeHandle - CreateChannelOnIOThread(ScopedPlatformHandle platform_handle, - ChannelInfo** channel_info); +CreateChannelOnIOThread(ScopedPlatformHandle platform_handle, + ChannelInfo** channel_info); typedef base::Callback<void(ChannelInfo*)> DidCreateChannelCallback; // Creates a channel asynchronously; may be called from any thread. // |platform_handle| should be a handle to a connected OS "pipe". // |io_thread_task_runner| should be the |TaskRunner| for the I/O thread. // |callback| should be the callback to call with the |ChannelInfo*|, which -// should eventually be passed to |DestroyChannel()| (or -// |DestroyChannelOnIOThread()|) to tear down the channel; the callback will be -// called using |callback_thread_task_runner| if that is non-null, or otherwise -// it will be called using |io_thread_task_runner|. Returns a handle to the -// bootstrap message pipe. +// should eventually be passed to |DestroyChannel()| to tear down the channel; +// the callback will be called using |callback_thread_task_runner| if that is +// non-null, or otherwise it will be called using |io_thread_task_runner|. +// Returns a handle to the bootstrap message pipe. MOJO_SYSTEM_IMPL_EXPORT ScopedMessagePipeHandle - CreateChannel(ScopedPlatformHandle platform_handle, - scoped_refptr<base::TaskRunner> io_thread_task_runner, - DidCreateChannelCallback callback, - scoped_refptr<base::TaskRunner> callback_thread_task_runner); - -// Destroys a channel that was created using either |CreateChannelOnIOThread()| -// or |CreateChannel()|; must only be called from the I/O thread. |channel_info| -// should be the "out" value from |CreateChannelOnIOThread()| or the value -// provided to the callback to |CreateChannel()|. -MOJO_SYSTEM_IMPL_EXPORT void DestroyChannelOnIOThread( - ChannelInfo* channel_info); +CreateChannel(ScopedPlatformHandle platform_handle, + scoped_refptr<base::TaskRunner> io_thread_task_runner, + DidCreateChannelCallback callback, + scoped_refptr<base::TaskRunner> callback_thread_task_runner); -// Destroys a channel (asynchronously) that was created using |CreateChannel()|; -// may be called from any thread. |channel_info| should be the value provided to -// the callback to |CreateChannel()|. +// Destroys a channel that was created using |CreateChannel()| (or +// |CreateChannelOnIOThread()|); may be called from any thread. |channel_info| +// should be the value provided to the callback to |CreateChannel()| (or +// returned by |CreateChannelOnIOThread()|). If called from the I/O thread, this +// will complete synchronously (in particular, it will post no tasks). MOJO_SYSTEM_IMPL_EXPORT void DestroyChannel(ChannelInfo* channel_info); // Inform the channel that it will soon be destroyed (doing so is optional). // This may be called from any thread, but the caller must ensure that this is -// called before |DestroyChannel()| or |DestroyChannelOnIOThread()|. +// called before |DestroyChannel()|. MOJO_SYSTEM_IMPL_EXPORT void WillDestroyChannelSoon(ChannelInfo* channel_info); // Creates a |MojoHandle| that wraps the given |PlatformHandle| (taking @@ -106,14 +108,14 @@ MOJO_SYSTEM_IMPL_EXPORT void WillDestroyChannelSoon(ChannelInfo* channel_info); // failure, which is different from what you'd expect from a Mojo API, but it // makes for a more convenient embedder API. MOJO_SYSTEM_IMPL_EXPORT MojoResult - CreatePlatformHandleWrapper(ScopedPlatformHandle platform_handle, - MojoHandle* platform_handle_wrapper_handle); +CreatePlatformHandleWrapper(ScopedPlatformHandle platform_handle, + MojoHandle* platform_handle_wrapper_handle); // Retrieves the |PlatformHandle| that was wrapped into a |MojoHandle| (using // |CreatePlatformHandleWrapper()| above). Note that the |MojoHandle| must still // be closed separately. MOJO_SYSTEM_IMPL_EXPORT MojoResult - PassWrappedPlatformHandle(MojoHandle platform_handle_wrapper_handle, - ScopedPlatformHandle* platform_handle); +PassWrappedPlatformHandle(MojoHandle platform_handle_wrapper_handle, + ScopedPlatformHandle* platform_handle); } // namespace embedder } // namespace mojo diff --git a/mojo/edk/embedder/embedder_internal.h b/mojo/edk/embedder/embedder_internal.h new file mode 100644 index 0000000..ab8388a --- /dev/null +++ b/mojo/edk/embedder/embedder_internal.h @@ -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. + +// This header contains internal details for the *implementation* of the +// embedder API. It should not be included by any public header (nor by users of +// the embedder API). + +#ifndef MOJO_EDK_EMBEDDER_EMBEDDER_INTERNAL_H_ +#define MOJO_EDK_EMBEDDER_EMBEDDER_INTERNAL_H_ + +#include <stdint.h> + +namespace mojo { + +namespace system { + +class ChannelManager; +class Core; + +// Repeat a typedef in mojo/edk/system/channel_manager.h, to avoid including it. +typedef uintptr_t ChannelId; + +} // namespace system + +namespace embedder { + +// This is a type that's opaque to users of the embedder API (which only +// gives/takes |ChannelInfo*|s). We make it a struct to make it +// template-friendly. +struct ChannelInfo { + explicit ChannelInfo(system::ChannelId channel_id = 0) + : channel_id(channel_id) {} + + system::ChannelId channel_id; +}; + +namespace internal { + +// Instance of |Core| used by the system functions (|Mojo...()|). +extern system::Core* g_core; + +// Instance of |ChannelManager| used by the channel management functions +// (|mojo::embedder::CreateChannel()|, etc.). +extern system::ChannelManager* g_channel_manager; + +} // namespace internal + +} // namepace embedder + +} // namespace mojo + +#endif // MOJO_EDK_EMBEDDER_EMBEDDER_INTERNAL_H_ diff --git a/mojo/edk/embedder/embedder_unittest.cc b/mojo/edk/embedder/embedder_unittest.cc index 5c4d0d8..16a5ce2 100644 --- a/mojo/edk/embedder/embedder_unittest.cc +++ b/mojo/edk/embedder/embedder_unittest.cc @@ -39,8 +39,7 @@ class ScopedTestChannel { did_create_channel_event_(true, false), channel_info_(nullptr) { bootstrap_message_pipe_ = - CreateChannel(platform_handle.Pass(), - io_thread_task_runner_, + CreateChannel(platform_handle.Pass(), io_thread_task_runner_, base::Bind(&ScopedTestChannel::DidCreateChannel, base::Unretained(this)), nullptr) @@ -51,12 +50,7 @@ class ScopedTestChannel { // Destructor: Shuts down the channel. (As noted above, for this to happen, // the I/O thread must be alive and pumping messages.) - ~ScopedTestChannel() { - system::test::PostTaskAndWait( - io_thread_task_runner_, - FROM_HERE, - base::Bind(&ScopedTestChannel::DestroyChannel, base::Unretained(this))); - } + ~ScopedTestChannel() { DestroyChannel(channel_info_); } // Waits for channel creation to be completed. void WaitForChannelCreationCompletion() { did_create_channel_event_.Wait(); } @@ -75,12 +69,6 @@ class ScopedTestChannel { did_create_channel_event_.Signal(); } - void DestroyChannel() { - CHECK(channel_info_); - DestroyChannelOnIOThread(channel_info_); - channel_info_ = nullptr; - } - scoped_refptr<base::TaskRunner> io_thread_task_runner_; // Valid from creation until whenever it gets closed (by the "owner" of this @@ -130,27 +118,18 @@ TEST_F(EmbedderTest, ChannelsBasic) { // We can write to a message pipe handle immediately. const char kHello[] = "hello"; EXPECT_EQ(MOJO_RESULT_OK, - MojoWriteMessage(server_mp, - kHello, - static_cast<uint32_t>(sizeof(kHello)), - nullptr, - 0, - MOJO_WRITE_MESSAGE_FLAG_NONE)); + MojoWriteMessage(server_mp, kHello, + static_cast<uint32_t>(sizeof(kHello)), nullptr, + 0, MOJO_WRITE_MESSAGE_FLAG_NONE)); // Now wait for the other side to become readable. - EXPECT_EQ( - MOJO_RESULT_OK, - MojoWait( - client_mp, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE)); + EXPECT_EQ(MOJO_RESULT_OK, MojoWait(client_mp, MOJO_HANDLE_SIGNAL_READABLE, + MOJO_DEADLINE_INDEFINITE)); char buffer[1000] = {}; uint32_t num_bytes = static_cast<uint32_t>(sizeof(buffer)); EXPECT_EQ(MOJO_RESULT_OK, - MojoReadMessage(client_mp, - buffer, - &num_bytes, - nullptr, - nullptr, + MojoReadMessage(client_mp, buffer, &num_bytes, nullptr, nullptr, MOJO_READ_MESSAGE_FLAG_NONE)); EXPECT_EQ(sizeof(kHello), num_bytes); EXPECT_STREQ(kHello, buffer); @@ -189,40 +168,28 @@ TEST_F(EmbedderTest, ChannelsHandlePassing) { // Write a message to |h0| (attaching nothing). const char kHello[] = "hello"; - EXPECT_EQ(MOJO_RESULT_OK, - MojoWriteMessage(h0, - kHello, - static_cast<uint32_t>(sizeof(kHello)), - nullptr, - 0, - MOJO_WRITE_MESSAGE_FLAG_NONE)); + EXPECT_EQ( + MOJO_RESULT_OK, + MojoWriteMessage(h0, kHello, static_cast<uint32_t>(sizeof(kHello)), + nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE)); // Write one message to |server_mp|, attaching |h1|. const char kWorld[] = "world!!!"; EXPECT_EQ(MOJO_RESULT_OK, - MojoWriteMessage(server_mp, - kWorld, - static_cast<uint32_t>(sizeof(kWorld)), - &h1, - 1, + MojoWriteMessage(server_mp, kWorld, + static_cast<uint32_t>(sizeof(kWorld)), &h1, 1, MOJO_WRITE_MESSAGE_FLAG_NONE)); h1 = MOJO_HANDLE_INVALID; // Write another message to |h0|. const char kFoo[] = "foo"; EXPECT_EQ(MOJO_RESULT_OK, - MojoWriteMessage(h0, - kFoo, - static_cast<uint32_t>(sizeof(kFoo)), - nullptr, - 0, - MOJO_WRITE_MESSAGE_FLAG_NONE)); + MojoWriteMessage(h0, kFoo, static_cast<uint32_t>(sizeof(kFoo)), + nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE)); // Wait for |client_mp| to become readable. - EXPECT_EQ( - MOJO_RESULT_OK, - MojoWait( - client_mp, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE)); + EXPECT_EQ(MOJO_RESULT_OK, MojoWait(client_mp, MOJO_HANDLE_SIGNAL_READABLE, + MOJO_DEADLINE_INDEFINITE)); // Read a message from |client_mp|. char buffer[1000] = {}; @@ -230,12 +197,8 @@ TEST_F(EmbedderTest, ChannelsHandlePassing) { MojoHandle handles[10] = {}; uint32_t num_handles = arraysize(handles); EXPECT_EQ(MOJO_RESULT_OK, - MojoReadMessage(client_mp, - buffer, - &num_bytes, - handles, - &num_handles, - MOJO_READ_MESSAGE_FLAG_NONE)); + MojoReadMessage(client_mp, buffer, &num_bytes, handles, + &num_handles, MOJO_READ_MESSAGE_FLAG_NONE)); EXPECT_EQ(sizeof(kWorld), num_bytes); EXPECT_STREQ(kWorld, buffer); EXPECT_EQ(1u, num_handles); @@ -243,9 +206,8 @@ TEST_F(EmbedderTest, ChannelsHandlePassing) { h1 = handles[0]; // Wait for |h1| to become readable. - EXPECT_EQ( - MOJO_RESULT_OK, - MojoWait(h1, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE)); + EXPECT_EQ(MOJO_RESULT_OK, MojoWait(h1, MOJO_HANDLE_SIGNAL_READABLE, + MOJO_DEADLINE_INDEFINITE)); // Read a message from |h1|. memset(buffer, 0, sizeof(buffer)); @@ -253,58 +215,41 @@ TEST_F(EmbedderTest, ChannelsHandlePassing) { memset(handles, 0, sizeof(handles)); num_handles = arraysize(handles); EXPECT_EQ(MOJO_RESULT_OK, - MojoReadMessage(h1, - buffer, - &num_bytes, - handles, - &num_handles, + MojoReadMessage(h1, buffer, &num_bytes, handles, &num_handles, MOJO_READ_MESSAGE_FLAG_NONE)); EXPECT_EQ(sizeof(kHello), num_bytes); EXPECT_STREQ(kHello, buffer); EXPECT_EQ(0u, num_handles); // Wait for |h1| to become readable (again). - EXPECT_EQ( - MOJO_RESULT_OK, - MojoWait(h1, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE)); + EXPECT_EQ(MOJO_RESULT_OK, MojoWait(h1, MOJO_HANDLE_SIGNAL_READABLE, + MOJO_DEADLINE_INDEFINITE)); // Read the second message from |h1|. memset(buffer, 0, sizeof(buffer)); num_bytes = static_cast<uint32_t>(sizeof(buffer)); EXPECT_EQ(MOJO_RESULT_OK, - MojoReadMessage(h1, - buffer, - &num_bytes, - nullptr, - nullptr, + MojoReadMessage(h1, buffer, &num_bytes, nullptr, nullptr, MOJO_READ_MESSAGE_FLAG_NONE)); EXPECT_EQ(sizeof(kFoo), num_bytes); EXPECT_STREQ(kFoo, buffer); // Write a message to |h1|. const char kBarBaz[] = "barbaz"; - EXPECT_EQ(MOJO_RESULT_OK, - MojoWriteMessage(h1, - kBarBaz, - static_cast<uint32_t>(sizeof(kBarBaz)), - nullptr, - 0, - MOJO_WRITE_MESSAGE_FLAG_NONE)); - - // Wait for |h0| to become readable. EXPECT_EQ( MOJO_RESULT_OK, - MojoWait(h0, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE)); + MojoWriteMessage(h1, kBarBaz, static_cast<uint32_t>(sizeof(kBarBaz)), + nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE)); + + // Wait for |h0| to become readable. + EXPECT_EQ(MOJO_RESULT_OK, MojoWait(h0, MOJO_HANDLE_SIGNAL_READABLE, + MOJO_DEADLINE_INDEFINITE)); // Read a message from |h0|. memset(buffer, 0, sizeof(buffer)); num_bytes = static_cast<uint32_t>(sizeof(buffer)); EXPECT_EQ(MOJO_RESULT_OK, - MojoReadMessage(h0, - buffer, - &num_bytes, - nullptr, - nullptr, + MojoReadMessage(h0, buffer, &num_bytes, nullptr, nullptr, MOJO_READ_MESSAGE_FLAG_NONE)); EXPECT_EQ(sizeof(kBarBaz), num_bytes); EXPECT_STREQ(kBarBaz, buffer); @@ -354,29 +299,20 @@ TEST_F(EmbedderTest, MultiprocessChannels) { // 1. Write a message to |server_mp| (attaching nothing). const char kHello[] = "hello"; EXPECT_EQ(MOJO_RESULT_OK, - MojoWriteMessage(server_mp, - kHello, - static_cast<uint32_t>(sizeof(kHello)), - nullptr, - 0, - MOJO_WRITE_MESSAGE_FLAG_NONE)); + MojoWriteMessage(server_mp, kHello, + static_cast<uint32_t>(sizeof(kHello)), nullptr, + 0, MOJO_WRITE_MESSAGE_FLAG_NONE)); // TODO(vtl): If the scope were ended immediately here (maybe after closing // |server_mp|), we die with a fatal error in |Channel::HandleLocalError()|. // 2. Read a message from |server_mp|. - EXPECT_EQ( - MOJO_RESULT_OK, - MojoWait( - server_mp, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE)); + EXPECT_EQ(MOJO_RESULT_OK, MojoWait(server_mp, MOJO_HANDLE_SIGNAL_READABLE, + MOJO_DEADLINE_INDEFINITE)); char buffer[1000] = {}; uint32_t num_bytes = static_cast<uint32_t>(sizeof(buffer)); EXPECT_EQ(MOJO_RESULT_OK, - MojoReadMessage(server_mp, - buffer, - &num_bytes, - nullptr, - nullptr, + MojoReadMessage(server_mp, buffer, &num_bytes, nullptr, nullptr, MOJO_READ_MESSAGE_FLAG_NONE)); const char kWorld[] = "world!"; EXPECT_EQ(sizeof(kWorld), num_bytes); @@ -389,41 +325,29 @@ TEST_F(EmbedderTest, MultiprocessChannels) { // 3. Write something to |mp0|. const char kFoo[] = "FOO"; EXPECT_EQ(MOJO_RESULT_OK, - MojoWriteMessage(mp0, - kFoo, - static_cast<uint32_t>(sizeof(kFoo)), - nullptr, - 0, - MOJO_WRITE_MESSAGE_FLAG_NONE)); + MojoWriteMessage(mp0, kFoo, static_cast<uint32_t>(sizeof(kFoo)), + nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE)); // 4. Write a message to |server_mp|, attaching |mp1|. const char kBar[] = "Bar"; - EXPECT_EQ(MOJO_RESULT_OK, - MojoWriteMessage(server_mp, - kBar, - static_cast<uint32_t>(sizeof(kBar)), - &mp1, - 1, - MOJO_WRITE_MESSAGE_FLAG_NONE)); + EXPECT_EQ( + MOJO_RESULT_OK, + MojoWriteMessage(server_mp, kBar, static_cast<uint32_t>(sizeof(kBar)), + &mp1, 1, MOJO_WRITE_MESSAGE_FLAG_NONE)); mp1 = MOJO_HANDLE_INVALID; // 5. Close |server_mp|. EXPECT_EQ(MOJO_RESULT_OK, MojoClose(server_mp)); // 9. Read a message from |mp0|, which should have |mp2| attached. - EXPECT_EQ( - MOJO_RESULT_OK, - MojoWait(mp0, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE)); + EXPECT_EQ(MOJO_RESULT_OK, MojoWait(mp0, MOJO_HANDLE_SIGNAL_READABLE, + MOJO_DEADLINE_INDEFINITE)); memset(buffer, 0, sizeof(buffer)); num_bytes = static_cast<uint32_t>(sizeof(buffer)); MojoHandle mp2 = MOJO_HANDLE_INVALID; uint32_t num_handles = 1; EXPECT_EQ(MOJO_RESULT_OK, - MojoReadMessage(mp0, - buffer, - &num_bytes, - &mp2, - &num_handles, + MojoReadMessage(mp0, buffer, &num_bytes, &mp2, &num_handles, MOJO_READ_MESSAGE_FLAG_NONE)); const char kQuux[] = "quux"; EXPECT_EQ(sizeof(kQuux), num_bytes); @@ -432,17 +356,12 @@ TEST_F(EmbedderTest, MultiprocessChannels) { EXPECT_NE(mp2, MOJO_HANDLE_INVALID); // 7. Read a message from |mp2|. - EXPECT_EQ( - MOJO_RESULT_OK, - MojoWait(mp2, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE)); + EXPECT_EQ(MOJO_RESULT_OK, MojoWait(mp2, MOJO_HANDLE_SIGNAL_READABLE, + MOJO_DEADLINE_INDEFINITE)); memset(buffer, 0, sizeof(buffer)); num_bytes = static_cast<uint32_t>(sizeof(buffer)); EXPECT_EQ(MOJO_RESULT_OK, - MojoReadMessage(mp2, - buffer, - &num_bytes, - nullptr, - nullptr, + MojoReadMessage(mp2, buffer, &num_bytes, nullptr, nullptr, MOJO_READ_MESSAGE_FLAG_NONE)); const char kBaz[] = "baz"; EXPECT_EQ(sizeof(kBaz), num_bytes); @@ -482,18 +401,12 @@ MOJO_MULTIPROCESS_TEST_CHILD_TEST(MultiprocessChannelsClient) { CHECK(client_channel.channel_info() != nullptr); // 1. Read the first message from |client_mp|. - EXPECT_EQ( - MOJO_RESULT_OK, - MojoWait( - client_mp, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE)); + EXPECT_EQ(MOJO_RESULT_OK, MojoWait(client_mp, MOJO_HANDLE_SIGNAL_READABLE, + MOJO_DEADLINE_INDEFINITE)); char buffer[1000] = {}; uint32_t num_bytes = static_cast<uint32_t>(sizeof(buffer)); EXPECT_EQ(MOJO_RESULT_OK, - MojoReadMessage(client_mp, - buffer, - &num_bytes, - nullptr, - nullptr, + MojoReadMessage(client_mp, buffer, &num_bytes, nullptr, nullptr, MOJO_READ_MESSAGE_FLAG_NONE)); const char kHello[] = "hello"; EXPECT_EQ(sizeof(kHello), num_bytes); @@ -502,18 +415,13 @@ MOJO_MULTIPROCESS_TEST_CHILD_TEST(MultiprocessChannelsClient) { // 2. Write a message to |client_mp| (attaching nothing). const char kWorld[] = "world!"; EXPECT_EQ(MOJO_RESULT_OK, - MojoWriteMessage(client_mp, - kWorld, - static_cast<uint32_t>(sizeof(kWorld)), - nullptr, - 0, - MOJO_WRITE_MESSAGE_FLAG_NONE)); + MojoWriteMessage(client_mp, kWorld, + static_cast<uint32_t>(sizeof(kWorld)), nullptr, + 0, MOJO_WRITE_MESSAGE_FLAG_NONE)); // 4. Read a message from |client_mp|, which should have |mp1| attached. - EXPECT_EQ( - MOJO_RESULT_OK, - MojoWait( - client_mp, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE)); + EXPECT_EQ(MOJO_RESULT_OK, MojoWait(client_mp, MOJO_HANDLE_SIGNAL_READABLE, + MOJO_DEADLINE_INDEFINITE)); // TODO(vtl): If the scope were to end here (and |client_mp| closed), we'd // die (again due to |Channel::HandleLocalError()|). memset(buffer, 0, sizeof(buffer)); @@ -521,11 +429,7 @@ MOJO_MULTIPROCESS_TEST_CHILD_TEST(MultiprocessChannelsClient) { MojoHandle mp1 = MOJO_HANDLE_INVALID; uint32_t num_handles = 1; EXPECT_EQ(MOJO_RESULT_OK, - MojoReadMessage(client_mp, - buffer, - &num_bytes, - &mp1, - &num_handles, + MojoReadMessage(client_mp, buffer, &num_bytes, &mp1, &num_handles, MOJO_READ_MESSAGE_FLAG_NONE)); const char kBar[] = "Bar"; EXPECT_EQ(sizeof(kBar), num_bytes); @@ -546,12 +450,8 @@ MOJO_MULTIPROCESS_TEST_CHILD_TEST(MultiprocessChannelsClient) { // 7. Write a message to |mp3|. const char kBaz[] = "baz"; EXPECT_EQ(MOJO_RESULT_OK, - MojoWriteMessage(mp3, - kBaz, - static_cast<uint32_t>(sizeof(kBaz)), - nullptr, - 0, - MOJO_WRITE_MESSAGE_FLAG_NONE)); + MojoWriteMessage(mp3, kBaz, static_cast<uint32_t>(sizeof(kBaz)), + nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE)); // 8. Close |mp3|. EXPECT_EQ(MOJO_RESULT_OK, MojoClose(mp3)); @@ -559,26 +459,17 @@ MOJO_MULTIPROCESS_TEST_CHILD_TEST(MultiprocessChannelsClient) { // 9. Write a message to |mp1|, attaching |mp2|. const char kQuux[] = "quux"; EXPECT_EQ(MOJO_RESULT_OK, - MojoWriteMessage(mp1, - kQuux, - static_cast<uint32_t>(sizeof(kQuux)), - &mp2, - 1, - MOJO_WRITE_MESSAGE_FLAG_NONE)); + MojoWriteMessage(mp1, kQuux, static_cast<uint32_t>(sizeof(kQuux)), + &mp2, 1, MOJO_WRITE_MESSAGE_FLAG_NONE)); mp2 = MOJO_HANDLE_INVALID; // 3. Read a message from |mp1|. - EXPECT_EQ( - MOJO_RESULT_OK, - MojoWait(mp1, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE)); + EXPECT_EQ(MOJO_RESULT_OK, MojoWait(mp1, MOJO_HANDLE_SIGNAL_READABLE, + MOJO_DEADLINE_INDEFINITE)); memset(buffer, 0, sizeof(buffer)); num_bytes = static_cast<uint32_t>(sizeof(buffer)); EXPECT_EQ(MOJO_RESULT_OK, - MojoReadMessage(mp1, - buffer, - &num_bytes, - nullptr, - nullptr, + MojoReadMessage(mp1, buffer, &num_bytes, nullptr, nullptr, MOJO_READ_MESSAGE_FLAG_NONE)); const char kFoo[] = "FOO"; EXPECT_EQ(sizeof(kFoo), num_bytes); diff --git a/mojo/edk/embedder/entrypoints.cc b/mojo/edk/embedder/entrypoints.cc new file mode 100644 index 0000000..7b2e53f --- /dev/null +++ b/mojo/edk/embedder/entrypoints.cc @@ -0,0 +1,155 @@ +// 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/edk/embedder/embedder_internal.h" +#include "mojo/edk/system/core.h" +#include "mojo/public/c/system/buffer.h" +#include "mojo/public/c/system/data_pipe.h" +#include "mojo/public/c/system/functions.h" +#include "mojo/public/c/system/message_pipe.h" + +using mojo::embedder::internal::g_core; +using mojo::system::MakeUserPointer; + +// Definitions of the system functions. +extern "C" { +MojoTimeTicks MojoGetTimeTicksNow() { + return g_core->GetTimeTicksNow(); +} + +MojoResult MojoClose(MojoHandle handle) { + return g_core->Close(handle); +} + +MojoResult MojoWait(MojoHandle handle, + MojoHandleSignals signals, + MojoDeadline deadline) { + return g_core->Wait(handle, signals, deadline, + mojo::system::NullUserPointer()); +} + +MojoResult MojoWaitMany(const MojoHandle* handles, + const MojoHandleSignals* signals, + uint32_t num_handles, + MojoDeadline deadline) { + uint32_t result_index = static_cast<uint32_t>(-1); + MojoResult result = g_core->WaitMany( + MakeUserPointer(handles), MakeUserPointer(signals), num_handles, deadline, + MakeUserPointer(&result_index), mojo::system::NullUserPointer()); + return (result == MOJO_RESULT_OK) ? static_cast<MojoResult>(result_index) + : result; +} + +MojoResult MojoCreateMessagePipe(const MojoCreateMessagePipeOptions* options, + MojoHandle* message_pipe_handle0, + MojoHandle* message_pipe_handle1) { + return g_core->CreateMessagePipe(MakeUserPointer(options), + MakeUserPointer(message_pipe_handle0), + MakeUserPointer(message_pipe_handle1)); +} + +MojoResult MojoWriteMessage(MojoHandle message_pipe_handle, + const void* bytes, + uint32_t num_bytes, + const MojoHandle* handles, + uint32_t num_handles, + MojoWriteMessageFlags flags) { + return g_core->WriteMessage(message_pipe_handle, MakeUserPointer(bytes), + num_bytes, MakeUserPointer(handles), num_handles, + flags); +} + +MojoResult MojoReadMessage(MojoHandle message_pipe_handle, + void* bytes, + uint32_t* num_bytes, + MojoHandle* handles, + uint32_t* num_handles, + MojoReadMessageFlags flags) { + return g_core->ReadMessage( + message_pipe_handle, MakeUserPointer(bytes), MakeUserPointer(num_bytes), + MakeUserPointer(handles), MakeUserPointer(num_handles), flags); +} + +MojoResult MojoCreateDataPipe(const MojoCreateDataPipeOptions* options, + MojoHandle* data_pipe_producer_handle, + MojoHandle* data_pipe_consumer_handle) { + return g_core->CreateDataPipe(MakeUserPointer(options), + MakeUserPointer(data_pipe_producer_handle), + MakeUserPointer(data_pipe_consumer_handle)); +} + +MojoResult MojoWriteData(MojoHandle data_pipe_producer_handle, + const void* elements, + uint32_t* num_elements, + MojoWriteDataFlags flags) { + return g_core->WriteData(data_pipe_producer_handle, MakeUserPointer(elements), + MakeUserPointer(num_elements), flags); +} + +MojoResult MojoBeginWriteData(MojoHandle data_pipe_producer_handle, + void** buffer, + uint32_t* buffer_num_elements, + MojoWriteDataFlags flags) { + return g_core->BeginWriteData(data_pipe_producer_handle, + MakeUserPointer(buffer), + MakeUserPointer(buffer_num_elements), flags); +} + +MojoResult MojoEndWriteData(MojoHandle data_pipe_producer_handle, + uint32_t num_elements_written) { + return g_core->EndWriteData(data_pipe_producer_handle, num_elements_written); +} + +MojoResult MojoReadData(MojoHandle data_pipe_consumer_handle, + void* elements, + uint32_t* num_elements, + MojoReadDataFlags flags) { + return g_core->ReadData(data_pipe_consumer_handle, MakeUserPointer(elements), + MakeUserPointer(num_elements), flags); +} + +MojoResult MojoBeginReadData(MojoHandle data_pipe_consumer_handle, + const void** buffer, + uint32_t* buffer_num_elements, + MojoReadDataFlags flags) { + return g_core->BeginReadData(data_pipe_consumer_handle, + MakeUserPointer(buffer), + MakeUserPointer(buffer_num_elements), flags); +} + +MojoResult MojoEndReadData(MojoHandle data_pipe_consumer_handle, + uint32_t num_elements_read) { + return g_core->EndReadData(data_pipe_consumer_handle, num_elements_read); +} + +MojoResult MojoCreateSharedBuffer( + const struct MojoCreateSharedBufferOptions* options, + uint64_t num_bytes, + MojoHandle* shared_buffer_handle) { + return g_core->CreateSharedBuffer(MakeUserPointer(options), num_bytes, + MakeUserPointer(shared_buffer_handle)); +} + +MojoResult MojoDuplicateBufferHandle( + MojoHandle buffer_handle, + const struct MojoDuplicateBufferHandleOptions* options, + MojoHandle* new_buffer_handle) { + return g_core->DuplicateBufferHandle(buffer_handle, MakeUserPointer(options), + MakeUserPointer(new_buffer_handle)); +} + +MojoResult MojoMapBuffer(MojoHandle buffer_handle, + uint64_t offset, + uint64_t num_bytes, + void** buffer, + MojoMapBufferFlags flags) { + return g_core->MapBuffer(buffer_handle, offset, num_bytes, + MakeUserPointer(buffer), flags); +} + +MojoResult MojoUnmapBuffer(void* buffer) { + return g_core->UnmapBuffer(MakeUserPointer(buffer)); +} + +} // extern "C" diff --git a/mojo/edk/embedder/platform_channel_pair_posix.cc b/mojo/edk/embedder/platform_channel_pair_posix.cc index f9886b5..2242cce 100644 --- a/mojo/edk/embedder/platform_channel_pair_posix.cc +++ b/mojo/edk/embedder/platform_channel_pair_posix.cc @@ -46,14 +46,10 @@ PlatformChannelPair::PlatformChannelPair() { // fail with |EPIPE| instead). On Linux, we have to use |send...()| with // |MSG_NOSIGNAL| -- which is not supported on Mac -- instead. int no_sigpipe = 1; - PCHECK( - setsockopt( - fds[0], SOL_SOCKET, SO_NOSIGPIPE, &no_sigpipe, sizeof(no_sigpipe)) == - 0); - PCHECK( - setsockopt( - fds[1], SOL_SOCKET, SO_NOSIGPIPE, &no_sigpipe, sizeof(no_sigpipe)) == - 0); + PCHECK(setsockopt(fds[0], SOL_SOCKET, SO_NOSIGPIPE, &no_sigpipe, + sizeof(no_sigpipe)) == 0); + PCHECK(setsockopt(fds[1], SOL_SOCKET, SO_NOSIGPIPE, &no_sigpipe, + sizeof(no_sigpipe)) == 0); #endif // defined(OS_MACOSX) server_handle_.reset(PlatformHandle(fds[0])); diff --git a/mojo/edk/embedder/platform_channel_pair_posix_unittest.cc b/mojo/edk/embedder/platform_channel_pair_posix_unittest.cc index 926bbc5..c3b1ef1 100644 --- a/mojo/edk/embedder/platform_channel_pair_posix_unittest.cc +++ b/mojo/edk/embedder/platform_channel_pair_posix_unittest.cc @@ -112,15 +112,15 @@ TEST_F(PlatformChannelPairPosixTest, SendReceiveData) { std::string send_string(1 << i, 'A' + i); EXPECT_EQ(static_cast<ssize_t>(send_string.size()), - PlatformChannelWrite( - server_handle.get(), send_string.data(), send_string.size())); + PlatformChannelWrite(server_handle.get(), send_string.data(), + send_string.size())); WaitReadable(client_handle.get()); char buf[10000] = {}; std::deque<PlatformHandle> received_handles; - ssize_t result = PlatformChannelRecvmsg( - client_handle.get(), buf, sizeof(buf), &received_handles); + ssize_t result = PlatformChannelRecvmsg(client_handle.get(), buf, + sizeof(buf), &received_handles); EXPECT_EQ(static_cast<ssize_t>(send_string.size()), result); EXPECT_EQ(send_string, std::string(buf, static_cast<size_t>(result))); EXPECT_TRUE(received_handles.empty()); @@ -155,9 +155,7 @@ TEST_F(PlatformChannelPairPosixTest, SendReceiveFDs) { struct iovec iov = {const_cast<char*>(kHello), sizeof(kHello)}; // We assume that the |sendmsg()| actually sends all the data. EXPECT_EQ(static_cast<ssize_t>(sizeof(kHello)), - PlatformChannelSendmsgWithHandles(server_handle.get(), - &iov, - 1, + PlatformChannelSendmsgWithHandles(server_handle.get(), &iov, 1, &platform_handles[0], platform_handles.size())); @@ -167,8 +165,8 @@ TEST_F(PlatformChannelPairPosixTest, SendReceiveFDs) { std::deque<PlatformHandle> received_handles; // We assume that the |recvmsg()| actually reads all the data. EXPECT_EQ(static_cast<ssize_t>(sizeof(kHello)), - PlatformChannelRecvmsg( - client_handle.get(), buf, sizeof(buf), &received_handles)); + PlatformChannelRecvmsg(client_handle.get(), buf, sizeof(buf), + &received_handles)); EXPECT_STREQ(kHello, buf); EXPECT_EQ(i, received_handles.size()); @@ -214,9 +212,7 @@ TEST_F(PlatformChannelPairPosixTest, AppendReceivedFDs) { struct iovec iov = {const_cast<char*>(kHello), sizeof(kHello)}; // We assume that the |sendmsg()| actually sends all the data. EXPECT_EQ(static_cast<ssize_t>(sizeof(kHello)), - PlatformChannelSendmsgWithHandles(server_handle.get(), - &iov, - 1, + PlatformChannelSendmsgWithHandles(server_handle.get(), &iov, 1, &platform_handles[0], platform_handles.size())); } @@ -230,8 +226,8 @@ TEST_F(PlatformChannelPairPosixTest, AppendReceivedFDs) { char buf[100] = {}; // We assume that the |recvmsg()| actually reads all the data. EXPECT_EQ(static_cast<ssize_t>(sizeof(kHello)), - PlatformChannelRecvmsg( - client_handle.get(), buf, sizeof(buf), &received_handles)); + PlatformChannelRecvmsg(client_handle.get(), buf, sizeof(buf), + &received_handles)); EXPECT_STREQ(kHello, buf); ASSERT_EQ(2u, received_handles.size()); EXPECT_FALSE(received_handles[0].is_valid()); diff --git a/mojo/edk/embedder/platform_channel_pair_win.cc b/mojo/edk/embedder/platform_channel_pair_win.cc index 4804eed..25306a6 100644 --- a/mojo/edk/embedder/platform_channel_pair_win.cc +++ b/mojo/edk/embedder/platform_channel_pair_win.cc @@ -23,8 +23,7 @@ namespace { std::wstring GeneratePipeName() { return base::StringPrintf(L"\\\\.\\pipe\\mojo.%u.%u.%I64u", - GetCurrentProcessId(), - GetCurrentThreadId(), + GetCurrentProcessId(), GetCurrentThreadId(), base::RandUint64()); } @@ -37,9 +36,7 @@ PlatformChannelPair::PlatformChannelPair() { PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | FILE_FLAG_FIRST_PIPE_INSTANCE; const DWORD kPipeMode = PIPE_TYPE_BYTE | PIPE_READMODE_BYTE; server_handle_.reset(PlatformHandle( - CreateNamedPipeW(pipe_name.c_str(), - kOpenMode, - kPipeMode, + CreateNamedPipeW(pipe_name.c_str(), kOpenMode, kPipeMode, 1, // Max instances. 4096, // Out buffer size. 4096, // In buffer size. @@ -56,12 +53,9 @@ PlatformChannelPair::PlatformChannelPair() { SECURITY_ATTRIBUTES security_attributes = { sizeof(SECURITY_ATTRIBUTES), nullptr, TRUE}; client_handle_.reset( - PlatformHandle(CreateFileW(pipe_name.c_str(), - kDesiredAccess, + PlatformHandle(CreateFileW(pipe_name.c_str(), kDesiredAccess, 0, // No sharing. - &security_attributes, - OPEN_EXISTING, - kFlags, + &security_attributes, OPEN_EXISTING, kFlags, nullptr))); // No template file. PCHECK(client_handle_.is_valid()); diff --git a/mojo/edk/embedder/platform_channel_utils_posix.h b/mojo/edk/embedder/platform_channel_utils_posix.h index 87176fb..34efcad 100644 --- a/mojo/edk/embedder/platform_channel_utils_posix.h +++ b/mojo/edk/embedder/platform_channel_utils_posix.h @@ -30,9 +30,9 @@ const size_t kPlatformChannelMaxNumHandles = 7; // never raise |SIGPIPE|. (Note: On Mac, the suppression of |SIGPIPE| is set up // by |PlatformChannelPair|.) MOJO_SYSTEM_IMPL_EXPORT ssize_t - PlatformChannelWrite(PlatformHandle h, const void* bytes, size_t num_bytes); +PlatformChannelWrite(PlatformHandle h, const void* bytes, size_t num_bytes); MOJO_SYSTEM_IMPL_EXPORT ssize_t - PlatformChannelWritev(PlatformHandle h, struct iovec* iov, size_t num_iov); +PlatformChannelWritev(PlatformHandle h, struct iovec* iov, size_t num_iov); // Writes data, and the given set of |PlatformHandle|s (i.e., file descriptors) // over the Unix domain socket given by |h| (e.g., created using @@ -43,11 +43,11 @@ MOJO_SYSTEM_IMPL_EXPORT ssize_t // specified by |iov|). (The handles are not closed, regardless of success or // failure.) MOJO_SYSTEM_IMPL_EXPORT ssize_t - PlatformChannelSendmsgWithHandles(PlatformHandle h, - struct iovec* iov, - size_t num_iov, - PlatformHandle* platform_handles, - size_t num_platform_handles); +PlatformChannelSendmsgWithHandles(PlatformHandle h, + struct iovec* iov, + size_t num_iov, + PlatformHandle* platform_handles, + size_t num_platform_handles); // TODO(vtl): Remove this once I've switched things over to // |PlatformChannelSendmsgWithHandles()|. @@ -65,10 +65,10 @@ MOJO_SYSTEM_IMPL_EXPORT bool PlatformChannelSendHandles(PlatformHandle h, // (in the control message) to |PlatformHandle|s (and append them to // |platform_handles|). (This also handles |EINTR|.) MOJO_SYSTEM_IMPL_EXPORT ssize_t - PlatformChannelRecvmsg(PlatformHandle h, - void* buf, - size_t num_bytes, - std::deque<PlatformHandle>* platform_handles); +PlatformChannelRecvmsg(PlatformHandle h, + void* buf, + size_t num_bytes, + std::deque<PlatformHandle>* platform_handles); } // namespace embedder } // namespace mojo diff --git a/mojo/edk/embedder/platform_handle_utils.h b/mojo/edk/embedder/platform_handle_utils.h index f594e21..b3d7a79 100644 --- a/mojo/edk/embedder/platform_handle_utils.h +++ b/mojo/edk/embedder/platform_handle_utils.h @@ -18,15 +18,14 @@ MOJO_SYSTEM_IMPL_EXPORT inline void CloseAllPlatformHandles( PlatformHandleContainer* platform_handles) { for (typename PlatformHandleContainer::iterator it = platform_handles->begin(); - it != platform_handles->end(); - ++it) + it != platform_handles->end(); ++it) it->CloseIfNecessary(); } // Duplicates the given |PlatformHandle| (which must be valid). (Returns an // invalid |ScopedPlatformHandle| on failure.) MOJO_SYSTEM_IMPL_EXPORT ScopedPlatformHandle - DuplicatePlatformHandle(PlatformHandle platform_handle); +DuplicatePlatformHandle(PlatformHandle platform_handle); } // namespace embedder } // namespace mojo diff --git a/mojo/edk/embedder/platform_handle_utils_win.cc b/mojo/edk/embedder/platform_handle_utils_win.cc index 12745d0..43d1331 100644 --- a/mojo/edk/embedder/platform_handle_utils_win.cc +++ b/mojo/edk/embedder/platform_handle_utils_win.cc @@ -15,12 +15,8 @@ ScopedPlatformHandle DuplicatePlatformHandle(PlatformHandle platform_handle) { DCHECK(platform_handle.is_valid()); HANDLE new_handle; - if (!DuplicateHandle(GetCurrentProcess(), - platform_handle.handle, - GetCurrentProcess(), - &new_handle, - 0, - TRUE, + if (!DuplicateHandle(GetCurrentProcess(), platform_handle.handle, + GetCurrentProcess(), &new_handle, 0, TRUE, DUPLICATE_SAME_ACCESS)) return ScopedPlatformHandle(); DCHECK_NE(new_handle, INVALID_HANDLE_VALUE); diff --git a/mojo/edk/embedder/simple_platform_shared_buffer_posix.cc b/mojo/edk/embedder/simple_platform_shared_buffer_posix.cc index ebb55ee..8dfcf44 100644 --- a/mojo/edk/embedder/simple_platform_shared_buffer_posix.cc +++ b/mojo/edk/embedder/simple_platform_shared_buffer_posix.cc @@ -127,12 +127,9 @@ scoped_ptr<PlatformSharedBufferMapping> SimplePlatformSharedBuffer::MapImpl( DCHECK_LE(static_cast<uint64_t>(real_offset), static_cast<uint64_t>(std::numeric_limits<off_t>::max())); - void* real_base = mmap(nullptr, - real_length, - PROT_READ | PROT_WRITE, - MAP_SHARED, - handle_.get().fd, - static_cast<off_t>(real_offset)); + void* real_base = + mmap(nullptr, real_length, PROT_READ | PROT_WRITE, MAP_SHARED, + handle_.get().fd, static_cast<off_t>(real_offset)); // |mmap()| should return |MAP_FAILED| (a.k.a. -1) on error. But it shouldn't // return null either. if (real_base == MAP_FAILED || !real_base) { diff --git a/mojo/edk/embedder/simple_platform_shared_buffer_win.cc b/mojo/edk/embedder/simple_platform_shared_buffer_win.cc index fd3de83..0737465 100644 --- a/mojo/edk/embedder/simple_platform_shared_buffer_win.cc +++ b/mojo/edk/embedder/simple_platform_shared_buffer_win.cc @@ -33,12 +33,9 @@ bool SimplePlatformSharedBuffer::Init() { // TODO(vtl): Unlike |base::SharedMemory|, we don't round up the size (to a // multiple of 64 KB). This may cause problems with NaCl. Cross this bridge // when we get there. crbug.com/210609 - handle_.reset(PlatformHandle(CreateFileMapping(INVALID_HANDLE_VALUE, - nullptr, - PAGE_READWRITE, - 0, - static_cast<DWORD>(num_bytes_), - nullptr))); + handle_.reset(PlatformHandle( + CreateFileMapping(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE, 0, + static_cast<DWORD>(num_bytes_), nullptr))); if (!handle_.is_valid()) { PLOG(ERROR) << "CreateFileMapping"; return false; @@ -68,11 +65,9 @@ scoped_ptr<PlatformSharedBufferMapping> SimplePlatformSharedBuffer::MapImpl( DCHECK_LE(static_cast<uint64_t>(real_offset), static_cast<uint64_t>(std::numeric_limits<DWORD>::max())); - void* real_base = MapViewOfFile(handle_.get().handle, - FILE_MAP_READ | FILE_MAP_WRITE, - 0, - static_cast<DWORD>(real_offset), - real_length); + void* real_base = + MapViewOfFile(handle_.get().handle, FILE_MAP_READ | FILE_MAP_WRITE, 0, + static_cast<DWORD>(real_offset), real_length); if (!real_base) { PLOG(ERROR) << "MapViewOfFile"; return nullptr; diff --git a/mojo/edk/embedder/test_embedder.cc b/mojo/edk/embedder/test_embedder.cc index 95d3be6..defab41 100644 --- a/mojo/edk/embedder/test_embedder.cc +++ b/mojo/edk/embedder/test_embedder.cc @@ -8,9 +8,10 @@ #include "base/macros.h" #include "base/memory/scoped_ptr.h" #include "mojo/edk/embedder/embedder.h" +#include "mojo/edk/embedder/embedder_internal.h" #include "mojo/edk/embedder/simple_platform_support.h" +#include "mojo/edk/system/channel_manager.h" #include "mojo/edk/system/core.h" -#include "mojo/edk/system/entrypoints.h" #include "mojo/edk/system/handle_table.h" namespace mojo { @@ -18,18 +19,17 @@ namespace mojo { namespace system { namespace internal { -bool ShutdownCheckNoLeaks(Core* core_impl) { +bool ShutdownCheckNoLeaks(Core* core) { // No point in taking the lock. const HandleTable::HandleToEntryMap& handle_to_entry_map = - core_impl->handle_table_.handle_to_entry_map_; + core->handle_table_.handle_to_entry_map_; if (handle_to_entry_map.empty()) return true; for (HandleTable::HandleToEntryMap::const_iterator it = handle_to_entry_map.begin(); - it != handle_to_entry_map.end(); - ++it) { + it != handle_to_entry_map.end(); ++it) { LOG(ERROR) << "Mojo embedder shutdown: Leaking handle " << (*it).first; } return false; @@ -46,12 +46,14 @@ void InitWithSimplePlatformSupport() { } bool Shutdown() { - system::Core* core = system::entrypoints::GetCore(); - CHECK(core); - system::entrypoints::SetCore(nullptr); - - bool rv = system::internal::ShutdownCheckNoLeaks(core); - delete core; + CHECK(internal::g_channel_manager); + delete internal::g_channel_manager; + internal::g_channel_manager = nullptr; + + CHECK(internal::g_core); + bool rv = system::internal::ShutdownCheckNoLeaks(internal::g_core); + delete internal::g_core; + internal::g_core = nullptr; return rv; } diff --git a/mojo/edk/embedder/test_embedder.h b/mojo/edk/embedder/test_embedder.h index b6203b4..76917ee 100644 --- a/mojo/edk/embedder/test_embedder.h +++ b/mojo/edk/embedder/test_embedder.h @@ -20,6 +20,9 @@ MOJO_SYSTEM_IMPL_EXPORT void InitWithSimplePlatformSupport(); // do more work to ensure that tests don't leak, etc.) Returns true if there // were no problems, false if there were leaks -- i.e., handles still open -- or // any other problems. +// +// Note: It is up to the caller to ensure that there are not outstanding +// callbacks from |CreateChannel()| before calling this. MOJO_SYSTEM_IMPL_EXPORT bool Shutdown(); } // namespace test |