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}
This commit is contained in:
build
content
browser
content.gypcontent_app.gypicontent_browser.gypicontent_child.gypicontent_common.gypicontent_common_mojo_bindings.gypicontent_gpu.gypicontent_plugin.gypicontent_ppapi_plugin.gypicontent_renderer.gypicontent_utility.gypidevice/battery
ipc/mojo
media/mojo/services
mojo
BUILD.gnmojo.gypmojo_base.gyp
edk
embedder
BUILD.gnchannel_info_forward.hchannel_init.ccchannel_init.hconfiguration.hembedder.ccembedder.hembedder_internal.hembedder_unittest.ccentrypoints.ccplatform_channel_pair_posix.ccplatform_channel_pair_posix_unittest.ccplatform_channel_pair_win.ccplatform_channel_utils_posix.hplatform_handle_utils.hplatform_handle_utils_win.ccsimple_platform_shared_buffer_posix.ccsimple_platform_shared_buffer_win.cctest_embedder.cctest_embedder.h
js
BUILD.gnDEPScore.cccore.hdrain_data.hhandle.cchandle.hhandle_close_observer.hmojo_runner_delegate.ccmojo_runner_delegate.hsupport.h
mojo_edk.gypmojo_edk_tests.gyptest
tests
BUILD.gnDEPSconnection_tests.jsjs_to_cpp.mojomjs_to_cpp_tests.ccjs_to_cpp_tests.jssample_service_tests.js
threading.ccthreading.hwaiting_callback.hsystem
BUILD.gnchannel.ccchannel.hchannel_endpoint.ccchannel_endpoint.hchannel_info.ccchannel_info.hchannel_manager.ccchannel_manager.hchannel_unittest.ccconfiguration.ccconfiguration.hconstants.hcore.cccore_test_base.cccore_unittest.ccdata_pipe.ccdata_pipe.hdata_pipe_consumer_dispatcher.ccdata_pipe_unittest.ccdispatcher.ccdispatcher.hdispatcher_unittest.ccentrypoints.hhandle_table.cclocal_data_pipe.cclocal_data_pipe.hlocal_data_pipe_unittest.ccmapping_table.ccmemory.ccmemory.hmessage_in_transit.ccmessage_pipe.ccmessage_pipe.hmessage_pipe_dispatcher.ccmessage_pipe_dispatcher_unittest.ccmessage_pipe_perftest.ccmessage_pipe_test_utils.ccmessage_pipe_unittest.ccmultiprocess_message_pipe_unittest.ccoptions_validation.hplatform_handle_dispatcher.ccraw_channel.ccraw_channel.hraw_channel_posix.ccraw_channel_unittest.ccraw_channel_win.ccremote_message_pipe_unittest.ccrun_all_unittests.ccshared_buffer_dispatcher.ccshared_buffer_dispatcher_unittest.ccsimple_dispatcher_unittest.cctest_utils.htransport_data.cctransport_data.hwaiter_test_utils.cc
test
public
VERSION
cpp
dart
go
system
impl
java
bindings
src
org
chromium
mojo
system
src
org
chromium
mojo
system
js
mojo_application.gnimojo_public.gyppython
tools
services
html_viewer
network
public
cpp
view_manager
interfaces
accessibility
clipboard
content_handler
geometry
gpu
input_events
native_viewport
navigation
network
surfaces
view_manager
window_manager
js
mojo_services_public.gypui/keyboard/webui
@ -42,13 +42,13 @@
|
||||
# NOTE: This list of targets is present because
|
||||
# mojo_base.gyp:mojo_base cannot be built on iOS, as
|
||||
# javascript-related targets cause v8 to be built.
|
||||
'../mojo/edk/mojo_edk.gyp:mojo_public_bindings_unittests',
|
||||
'../mojo/edk/mojo_edk.gyp:mojo_public_environment_unittests',
|
||||
'../mojo/edk/mojo_edk.gyp:mojo_public_system_perftests',
|
||||
'../mojo/edk/mojo_edk.gyp:mojo_public_system_unittests',
|
||||
'../mojo/edk/mojo_edk.gyp:mojo_public_utility_unittests',
|
||||
'../mojo/edk/mojo_edk_tests.gyp:mojo_public_bindings_unittests',
|
||||
'../mojo/edk/mojo_edk_tests.gyp:mojo_public_environment_unittests',
|
||||
'../mojo/edk/mojo_edk_tests.gyp:mojo_public_system_perftests',
|
||||
'../mojo/edk/mojo_edk_tests.gyp:mojo_public_system_unittests',
|
||||
'../mojo/edk/mojo_edk_tests.gyp:mojo_public_utility_unittests',
|
||||
'../mojo/edk/mojo_edk.gyp:mojo_system_impl',
|
||||
'../mojo/edk/mojo_edk.gyp:mojo_system_unittests',
|
||||
'../mojo/edk/mojo_edk_tests.gyp:mojo_system_unittests',
|
||||
'../mojo/mojo_base.gyp:mojo_common_lib',
|
||||
'../mojo/mojo_base.gyp:mojo_common_unittests',
|
||||
'../mojo/public/mojo_public.gyp:mojo_cpp_bindings',
|
||||
|
@ -82,9 +82,6 @@ class PingBrowserTargetImpl : public BrowserTargetImpl {
|
||||
|
||||
~PingBrowserTargetImpl() override {}
|
||||
|
||||
// mojo::InterfaceImpl<BrowserTarget> overrides:
|
||||
void OnConnectionEstablished() override { client()->Ping(); }
|
||||
|
||||
// Quit the RunLoop when called.
|
||||
void PingResponse() override {
|
||||
got_message = true;
|
||||
@ -134,6 +131,7 @@ class PingTestWebUIController : public TestWebUIController {
|
||||
void CreateHandler(mojo::InterfaceRequest<BrowserTarget> request) {
|
||||
browser_target_.reset(mojo::WeakBindToRequest(
|
||||
new PingBrowserTargetImpl(run_loop_), &request));
|
||||
browser_target_->client()->Ping();
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -24,9 +24,9 @@
|
||||
'conditions': [
|
||||
['OS != "ios"', {
|
||||
'includes': [
|
||||
'../build/win_precompile.gypi',
|
||||
'content_common_mojo_bindings.gypi',
|
||||
'content_resources.gypi',
|
||||
'../build/win_precompile.gypi',
|
||||
],
|
||||
}],
|
||||
['OS == "win"', {
|
||||
@ -75,6 +75,7 @@
|
||||
['OS != "ios"', {
|
||||
'dependencies': [
|
||||
'content_child',
|
||||
'content_common_mojo_bindings',
|
||||
'content_gpu',
|
||||
'content_plugin',
|
||||
'content_ppapi_plugin',
|
||||
@ -174,6 +175,7 @@
|
||||
}],
|
||||
['OS != "ios"', {
|
||||
'dependencies': [
|
||||
'content_common_mojo_bindings',
|
||||
'content_resources',
|
||||
],
|
||||
}],
|
||||
@ -190,6 +192,7 @@
|
||||
'conditions': [
|
||||
['OS != "ios"', {
|
||||
'dependencies': [
|
||||
'content_common_mojo_bindings',
|
||||
'content_resources',
|
||||
],
|
||||
}],
|
||||
@ -306,6 +309,11 @@
|
||||
'../v8/src/third_party/vtune/v8vtune.gyp:v8_vtune',
|
||||
],
|
||||
}],
|
||||
['OS != "ios"', {
|
||||
'dependencies': [
|
||||
'content_common_mojo_bindings',
|
||||
]
|
||||
}]
|
||||
],
|
||||
'includes': [
|
||||
'content_app.gypi',
|
||||
@ -427,6 +435,7 @@
|
||||
'../device/battery/battery.gyp:device_battery_java',
|
||||
'../media/media.gyp:media_java',
|
||||
'../mojo/mojo_base.gyp:mojo_system_java',
|
||||
'../mojo/public/mojo_public.gyp:mojo_application_bindings',
|
||||
'../mojo/public/mojo_public.gyp:mojo_bindings_java',
|
||||
'../net/net.gyp:net',
|
||||
'../ui/android/ui_android.gyp:ui_java',
|
||||
|
@ -66,7 +66,6 @@
|
||||
'dependencies': [
|
||||
'../mojo/edk/mojo_edk.gyp:mojo_system_impl',
|
||||
'../mojo/mojo_base.gyp:mojo_environment_chromium',
|
||||
'../mojo/public/mojo_public.gyp:mojo_application_bindings',
|
||||
],
|
||||
}],
|
||||
],
|
||||
|
@ -1666,10 +1666,8 @@
|
||||
'app/strings/content_strings.gyp:content_strings',
|
||||
'browser/devtools/devtools_resources.gyp:devtools_resources',
|
||||
'browser/devtools/devtools.gyp:devtools_protocol_handler',
|
||||
'content_common_mojo_bindings',
|
||||
'../cc/cc.gyp:cc',
|
||||
'../cc/cc.gyp:cc_surfaces',
|
||||
'../mojo/public/mojo_public.gyp:mojo_application_bindings',
|
||||
'../mojo/public/mojo_public.gyp:mojo_cpp_bindings',
|
||||
'../mojo/public/mojo_public.gyp:mojo_js_bindings',
|
||||
'../net/net.gyp:http_server',
|
||||
|
@ -8,7 +8,6 @@
|
||||
'../components/tracing.gyp:tracing',
|
||||
'../mojo/mojo_base.gyp:mojo_environment_chromium',
|
||||
'../mojo/mojo_base.gyp:mojo_common_lib',
|
||||
'../mojo/public/mojo_public.gyp:mojo_application_bindings',
|
||||
'../skia/skia.gyp:skia',
|
||||
'../ui/base/ui_base.gyp:ui_base',
|
||||
'../ui/gfx/gfx.gyp:gfx',
|
||||
|
@ -572,7 +572,6 @@
|
||||
'../media/media.gyp:shared_memory_support',
|
||||
'../mojo/edk/mojo_edk.gyp:mojo_system_impl',
|
||||
'../mojo/mojo_base.gyp:mojo_environment_chromium',
|
||||
'../mojo/public/mojo_public.gyp:mojo_application_bindings',
|
||||
'../mojo/public/mojo_public.gyp:mojo_cpp_bindings',
|
||||
'../storage/storage_browser.gyp:storage',
|
||||
'../storage/storage_common.gyp:storage_common',
|
||||
|
@ -4,30 +4,33 @@
|
||||
|
||||
{
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'content_common_mojo_bindings_mojom',
|
||||
'type': 'none',
|
||||
'variables': {
|
||||
'mojom_files': [
|
||||
# NOTE: Sources duplicated in //content/common/BUILD.gn:mojo_bindings.
|
||||
'common/geolocation_service.mojom',
|
||||
'common/permission_service.mojom',
|
||||
'common/render_frame_setup.mojom',
|
||||
|
||||
# NOTE: Sources duplicated in
|
||||
# //content/public/common/BUILD.gn:mojo_bindings.
|
||||
'public/common/mojo_geoposition.mojom',
|
||||
],
|
||||
},
|
||||
'includes': [ '../mojo/public/tools/bindings/mojom_bindings_generator_explicit.gypi' ],
|
||||
},
|
||||
{
|
||||
'target_name': 'content_common_mojo_bindings',
|
||||
'type': 'static_library',
|
||||
'variables': { 'enable_wexit_time_destructors': 1, },
|
||||
'dependencies': [
|
||||
'content_common_mojo_bindings_mojom',
|
||||
'../mojo/mojo_base.gyp:mojo_environment_chromium',
|
||||
'../mojo/public/mojo_public.gyp:mojo_application_bindings',
|
||||
'../mojo/public/mojo_public.gyp:mojo_cpp_bindings',
|
||||
],
|
||||
'sources': [
|
||||
# NOTE: Sources duplicated in //content/common/BUILD.gn:mojo_bindings.
|
||||
'common/geolocation_service.mojom',
|
||||
'common/permission_service.mojom',
|
||||
'common/render_frame_setup.mojom',
|
||||
|
||||
# NOTE: Sources duplicated in
|
||||
# //content/public/common/BUILD.gn:mojo_bindings.
|
||||
'public/common/mojo_geoposition.mojom',
|
||||
],
|
||||
'includes': [ '../mojo/public/tools/bindings/mojom_bindings_generator.gypi' ],
|
||||
'export_dependent_settings': [
|
||||
'../mojo/mojo_base.gyp:mojo_environment_chromium',
|
||||
'../mojo/public/mojo_public.gyp:mojo_application_bindings',
|
||||
'../mojo/public/mojo_public.gyp:mojo_cpp_bindings',
|
||||
],
|
||||
]
|
||||
},
|
||||
],
|
||||
]
|
||||
}
|
||||
|
@ -5,7 +5,6 @@
|
||||
{
|
||||
'dependencies': [
|
||||
'../base/base.gyp:base',
|
||||
'../mojo/public/mojo_public.gyp:mojo_application_bindings',
|
||||
'../skia/skia.gyp:skia',
|
||||
'../ui/gl/gl.gyp:gl',
|
||||
],
|
||||
|
@ -6,7 +6,6 @@
|
||||
'conditions': [
|
||||
['enable_plugins==1 and OS!="linux"', {
|
||||
'dependencies': [
|
||||
'../mojo/public/mojo_public.gyp:mojo_application_bindings',
|
||||
'../skia/skia.gyp:skia',
|
||||
'../third_party/WebKit/public/blink.gyp:blink',
|
||||
'../third_party/npapi/npapi.gyp:npapi',
|
||||
|
@ -7,7 +7,6 @@
|
||||
['enable_plugins==1', {
|
||||
'dependencies': [
|
||||
'../base/base.gyp:base',
|
||||
'../mojo/public/mojo_public.gyp:mojo_application_bindings',
|
||||
'../ppapi/ppapi_internal.gyp:ppapi_ipc',
|
||||
'../ui/base/ui_base.gyp:ui_base',
|
||||
'../ui/gfx/gfx.gyp:gfx',
|
||||
|
@ -4,7 +4,6 @@
|
||||
|
||||
{
|
||||
'dependencies': [
|
||||
'content_common_mojo_bindings',
|
||||
'../base/base.gyp:base',
|
||||
'../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations',
|
||||
'../cc/cc.gyp:cc',
|
||||
@ -18,7 +17,6 @@
|
||||
'../media/media.gyp:media',
|
||||
'../mojo/edk/mojo_edk.gyp:mojo_js_lib',
|
||||
'../mojo/mojo_base.gyp:mojo_environment_chromium',
|
||||
'../mojo/public/mojo_public.gyp:mojo_application_bindings',
|
||||
'../net/net.gyp:net',
|
||||
'../skia/skia.gyp:skia',
|
||||
'../storage/storage_common.gyp:storage_common',
|
||||
|
@ -6,7 +6,6 @@
|
||||
'dependencies': [
|
||||
'../base/base.gyp:base',
|
||||
'../courgette/courgette.gyp:courgette_lib',
|
||||
'../mojo/public/mojo_public.gyp:mojo_application_bindings',
|
||||
],
|
||||
'sources': [
|
||||
'public/utility/content_utility_client.cc',
|
||||
|
@ -11,24 +11,26 @@ namespace device {
|
||||
// static
|
||||
void BatteryMonitorImpl::Create(
|
||||
mojo::InterfaceRequest<BatteryMonitor> request) {
|
||||
BindToRequest(new BatteryMonitorImpl(), &request);
|
||||
new BatteryMonitorImpl(request.Pass());
|
||||
}
|
||||
|
||||
BatteryMonitorImpl::BatteryMonitorImpl() {
|
||||
BatteryMonitorImpl::BatteryMonitorImpl(
|
||||
mojo::InterfaceRequest<BatteryMonitor> request)
|
||||
: binding_(this, request.Pass()),
|
||||
subscription_(BatteryStatusService::GetInstance()->AddCallback(
|
||||
base::Bind(&BatteryMonitorImpl::DidChange, base::Unretained(this)))) {
|
||||
}
|
||||
|
||||
BatteryMonitorImpl::~BatteryMonitorImpl() {
|
||||
}
|
||||
|
||||
void BatteryMonitorImpl::OnConnectionEstablished() {
|
||||
subscription_ = BatteryStatusService::GetInstance()->AddCallback(
|
||||
base::Bind(&BatteryMonitorImpl::DidChange, base::Unretained(this)));
|
||||
void BatteryMonitorImpl::RegisterSubscription() {
|
||||
}
|
||||
|
||||
void BatteryMonitorImpl::DidChange(const BatteryStatus& battery_status) {
|
||||
BatteryStatusPtr status(BatteryStatus::New());
|
||||
*status = battery_status;
|
||||
client()->DidChange(status.Pass());
|
||||
binding_.client()->DidChange(status.Pass());
|
||||
}
|
||||
|
||||
} // namespace device
|
||||
|
@ -2,31 +2,33 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef DEVICE_BATTERY_BATTERY_MONITOR_IMPL_H_
|
||||
#define DEVICE_BATTERY_BATTERY_MONITOR_IMPL_H_
|
||||
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "device/battery/battery_export.h"
|
||||
#include "device/battery/battery_monitor.mojom.h"
|
||||
#include "device/battery/battery_status_service.h"
|
||||
|
||||
#ifndef DEVICE_BATTERY_BATTERY_MONITOR_IMPL_H_
|
||||
#define DEVICE_BATTERY_BATTERY_MONITOR_IMPL_H_
|
||||
#include "mojo/public/cpp/bindings/strong_binding.h"
|
||||
|
||||
namespace device {
|
||||
|
||||
class BatteryMonitorImpl : public mojo::InterfaceImpl<BatteryMonitor> {
|
||||
class BatteryMonitorImpl : public BatteryMonitor {
|
||||
public:
|
||||
DEVICE_BATTERY_EXPORT static void Create(
|
||||
mojo::InterfaceRequest<BatteryMonitor> request);
|
||||
|
||||
private:
|
||||
BatteryMonitorImpl();
|
||||
explicit BatteryMonitorImpl(mojo::InterfaceRequest<BatteryMonitor> request);
|
||||
~BatteryMonitorImpl() override;
|
||||
|
||||
// mojo::InterfaceImpl<..> methods:
|
||||
void OnConnectionEstablished() override;
|
||||
|
||||
void RegisterSubscription();
|
||||
void DidChange(const BatteryStatus& battery_status);
|
||||
|
||||
mojo::StrongBinding<BatteryMonitor> binding_;
|
||||
scoped_ptr<BatteryStatusService::BatteryUpdateSubscription> subscription_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(BatteryMonitorImpl);
|
||||
};
|
||||
|
||||
} // namespace device
|
||||
|
@ -168,7 +168,7 @@ void ServerChannelMojo::Close() {
|
||||
|
||||
void ChannelMojo::ChannelInfoDeleter::operator()(
|
||||
mojo::embedder::ChannelInfo* ptr) const {
|
||||
mojo::embedder::DestroyChannelOnIOThread(ptr);
|
||||
mojo::embedder::DestroyChannel(ptr);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -2,6 +2,8 @@
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
import("//mojo/public/mojo_application.gni")
|
||||
|
||||
# Things needed by multiple targets, like renderer_impl and renderer_app.
|
||||
# GYP version: media/media.gyp:media_mojo_lib
|
||||
source_set("lib") {
|
||||
@ -49,7 +51,7 @@ source_set("renderer_impl_lib") {
|
||||
|
||||
# mojo media::Renderer application.
|
||||
# GYP version: media/media.gyp:mojo_media_renderer_app
|
||||
shared_library("renderer_app") {
|
||||
mojo_native_application("renderer_app") {
|
||||
output_name = "mojo_media_renderer_app"
|
||||
|
||||
deps = [
|
||||
@ -99,7 +101,7 @@ test("mojo_media_lib_unittests") {
|
||||
# libraries.
|
||||
# TODO(msw): Fix GYP build for ApplicationTestBase so that we can add a GYP
|
||||
# version of this test.
|
||||
shared_library("media_renderer_apptest") {
|
||||
mojo_native_application("media_renderer_apptest") {
|
||||
testonly = true
|
||||
output_name = "mojo_media_renderer_apptest"
|
||||
|
||||
|
@ -51,7 +51,7 @@ void MojoDemuxerStreamImpl::OnBufferReady(
|
||||
mojo::MediaDecoderBuffer::From(buffer));
|
||||
}
|
||||
|
||||
void MojoDemuxerStreamImpl::OnConnectionEstablished() {
|
||||
void MojoDemuxerStreamImpl::DidConnect() {
|
||||
// This is called when our DemuxerStreamClient has connected itself and is
|
||||
// ready to receive messages. Send an initial config and notify it that
|
||||
// we are now ready for business.
|
||||
|
@ -28,8 +28,7 @@ class MojoDemuxerStreamImpl : public mojo::InterfaceImpl<mojo::DemuxerStream> {
|
||||
mojo::MediaDecoderBufferPtr)>& callback)
|
||||
override;
|
||||
|
||||
// mojo::InterfaceImpl overrides.
|
||||
void OnConnectionEstablished() override;
|
||||
void DidConnect();
|
||||
|
||||
private:
|
||||
// |callback| is the callback that was passed to the initiating Read()
|
||||
|
@ -63,12 +63,16 @@ void MojoRendererImpl::Initialize(
|
||||
demuxer_stream_provider_->GetStream(DemuxerStream::VIDEO);
|
||||
|
||||
mojo::DemuxerStreamPtr audio_stream;
|
||||
if (audio)
|
||||
mojo::BindToProxy(new MojoDemuxerStreamImpl(audio), &audio_stream);
|
||||
if (audio) {
|
||||
mojo::BindToProxy(new MojoDemuxerStreamImpl(audio), &audio_stream)
|
||||
->DidConnect();
|
||||
}
|
||||
|
||||
mojo::DemuxerStreamPtr video_stream;
|
||||
if (video)
|
||||
mojo::BindToProxy(new MojoDemuxerStreamImpl(video), &video_stream);
|
||||
if (video) {
|
||||
mojo::BindToProxy(new MojoDemuxerStreamImpl(video), &video_stream)
|
||||
->DidConnect();
|
||||
}
|
||||
|
||||
remote_audio_renderer_->Initialize(
|
||||
audio_stream.Pass(),
|
||||
|
@ -26,7 +26,7 @@ group("tests") {
|
||||
deps = [
|
||||
"//mojo/common:mojo_common_unittests",
|
||||
"//mojo/converters/surfaces/tests:mojo_surfaces_lib_unittests",
|
||||
"//mojo/edk/js/tests:js_unittests",
|
||||
"//mojo/edk/js/test:js_unittests",
|
||||
"//mojo/edk/system:mojo_message_pipe_perftests",
|
||||
"//mojo/edk/system:mojo_system_unittests",
|
||||
"//mojo/public/c/system/tests:perftests",
|
||||
|
@ -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
|
||||
|
||||
deps = [
|
||||
"//base",
|
||||
"//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",
|
||||
]
|
||||
|
||||
deps = [
|
||||
"//base",
|
||||
"//base/test:test_support",
|
||||
"//mojo/edk/test:test_support",
|
||||
"//mojo/edk/system",
|
||||
"//testing/gtest",
|
||||
]
|
||||
}
|
||||
|
@ -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_
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
68
mojo/edk/embedder/configuration.h
Normal file
68
mojo/edk/embedder/configuration.h
Normal file
@ -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_
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
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);
|
||||
|
||||
// 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
|
||||
|
53
mojo/edk/embedder/embedder_internal.h
Normal file
53
mojo/edk/embedder/embedder_internal.h
Normal file
@ -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_
|
@ -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);
|
||||
|
@ -2,35 +2,16 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "mojo/edk/system/entrypoints.h"
|
||||
|
||||
#include "base/logging.h"
|
||||
#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"
|
||||
|
||||
static mojo::system::Core* g_core = nullptr;
|
||||
|
||||
using mojo::embedder::internal::g_core;
|
||||
using mojo::system::MakeUserPointer;
|
||||
|
||||
namespace mojo {
|
||||
namespace system {
|
||||
namespace entrypoints {
|
||||
|
||||
void SetCore(Core* core) {
|
||||
g_core = core;
|
||||
}
|
||||
|
||||
Core* GetCore() {
|
||||
return g_core;
|
||||
}
|
||||
|
||||
} // namespace entrypoints
|
||||
} // namepace system
|
||||
} // namespace mojo
|
||||
|
||||
// Definitions of the system functions.
|
||||
extern "C" {
|
||||
MojoTimeTicks MojoGetTimeTicksNow() {
|
||||
@ -44,8 +25,8 @@ MojoResult MojoClose(MojoHandle handle) {
|
||||
MojoResult MojoWait(MojoHandle handle,
|
||||
MojoHandleSignals signals,
|
||||
MojoDeadline deadline) {
|
||||
return g_core->Wait(
|
||||
handle, signals, deadline, mojo::system::NullUserPointer());
|
||||
return g_core->Wait(handle, signals, deadline,
|
||||
mojo::system::NullUserPointer());
|
||||
}
|
||||
|
||||
MojoResult MojoWaitMany(const MojoHandle* handles,
|
||||
@ -53,12 +34,9 @@ MojoResult MojoWaitMany(const MojoHandle* handles,
|
||||
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());
|
||||
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;
|
||||
}
|
||||
@ -77,11 +55,8 @@ MojoResult MojoWriteMessage(MojoHandle message_pipe_handle,
|
||||
const MojoHandle* handles,
|
||||
uint32_t num_handles,
|
||||
MojoWriteMessageFlags flags) {
|
||||
return g_core->WriteMessage(message_pipe_handle,
|
||||
MakeUserPointer(bytes),
|
||||
num_bytes,
|
||||
MakeUserPointer(handles),
|
||||
num_handles,
|
||||
return g_core->WriteMessage(message_pipe_handle, MakeUserPointer(bytes),
|
||||
num_bytes, MakeUserPointer(handles), num_handles,
|
||||
flags);
|
||||
}
|
||||
|
||||
@ -91,12 +66,9 @@ MojoResult MojoReadMessage(MojoHandle message_pipe_handle,
|
||||
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);
|
||||
return g_core->ReadMessage(
|
||||
message_pipe_handle, MakeUserPointer(bytes), MakeUserPointer(num_bytes),
|
||||
MakeUserPointer(handles), MakeUserPointer(num_handles), flags);
|
||||
}
|
||||
|
||||
MojoResult MojoCreateDataPipe(const MojoCreateDataPipeOptions* options,
|
||||
@ -111,10 +83,8 @@ 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);
|
||||
return g_core->WriteData(data_pipe_producer_handle, MakeUserPointer(elements),
|
||||
MakeUserPointer(num_elements), flags);
|
||||
}
|
||||
|
||||
MojoResult MojoBeginWriteData(MojoHandle data_pipe_producer_handle,
|
||||
@ -123,8 +93,7 @@ MojoResult MojoBeginWriteData(MojoHandle data_pipe_producer_handle,
|
||||
MojoWriteDataFlags flags) {
|
||||
return g_core->BeginWriteData(data_pipe_producer_handle,
|
||||
MakeUserPointer(buffer),
|
||||
MakeUserPointer(buffer_num_elements),
|
||||
flags);
|
||||
MakeUserPointer(buffer_num_elements), flags);
|
||||
}
|
||||
|
||||
MojoResult MojoEndWriteData(MojoHandle data_pipe_producer_handle,
|
||||
@ -136,10 +105,8 @@ 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);
|
||||
return g_core->ReadData(data_pipe_consumer_handle, MakeUserPointer(elements),
|
||||
MakeUserPointer(num_elements), flags);
|
||||
}
|
||||
|
||||
MojoResult MojoBeginReadData(MojoHandle data_pipe_consumer_handle,
|
||||
@ -148,8 +115,7 @@ MojoResult MojoBeginReadData(MojoHandle data_pipe_consumer_handle,
|
||||
MojoReadDataFlags flags) {
|
||||
return g_core->BeginReadData(data_pipe_consumer_handle,
|
||||
MakeUserPointer(buffer),
|
||||
MakeUserPointer(buffer_num_elements),
|
||||
flags);
|
||||
MakeUserPointer(buffer_num_elements), flags);
|
||||
}
|
||||
|
||||
MojoResult MojoEndReadData(MojoHandle data_pipe_consumer_handle,
|
||||
@ -161,8 +127,7 @@ MojoResult MojoCreateSharedBuffer(
|
||||
const struct MojoCreateSharedBufferOptions* options,
|
||||
uint64_t num_bytes,
|
||||
MojoHandle* shared_buffer_handle) {
|
||||
return g_core->CreateSharedBuffer(MakeUserPointer(options),
|
||||
num_bytes,
|
||||
return g_core->CreateSharedBuffer(MakeUserPointer(options), num_bytes,
|
||||
MakeUserPointer(shared_buffer_handle));
|
||||
}
|
||||
|
||||
@ -170,8 +135,7 @@ MojoResult MojoDuplicateBufferHandle(
|
||||
MojoHandle buffer_handle,
|
||||
const struct MojoDuplicateBufferHandleOptions* options,
|
||||
MojoHandle* new_buffer_handle) {
|
||||
return g_core->DuplicateBufferHandle(buffer_handle,
|
||||
MakeUserPointer(options),
|
||||
return g_core->DuplicateBufferHandle(buffer_handle, MakeUserPointer(options),
|
||||
MakeUserPointer(new_buffer_handle));
|
||||
}
|
||||
|
||||
@ -180,8 +144,8 @@ MojoResult MojoMapBuffer(MojoHandle buffer_handle,
|
||||
uint64_t num_bytes,
|
||||
void** buffer,
|
||||
MojoMapBufferFlags flags) {
|
||||
return g_core->MapBuffer(
|
||||
buffer_handle, offset, num_bytes, MakeUserPointer(buffer), flags);
|
||||
return g_core->MapBuffer(buffer_handle, offset, num_bytes,
|
||||
MakeUserPointer(buffer), flags);
|
||||
}
|
||||
|
||||
MojoResult MojoUnmapBuffer(void* buffer) {
|
@ -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]));
|
||||
|
@ -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());
|
||||
|
@ -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());
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
CHECK(internal::g_channel_manager);
|
||||
delete internal::g_channel_manager;
|
||||
internal::g_channel_manager = nullptr;
|
||||
|
||||
bool rv = system::internal::ShutdownCheckNoLeaks(core);
|
||||
delete core;
|
||||
CHECK(internal::g_core);
|
||||
bool rv = system::internal::ShutdownCheckNoLeaks(internal::g_core);
|
||||
delete internal::g_core;
|
||||
internal::g_core = nullptr;
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -11,8 +11,12 @@ source_set("js") {
|
||||
"handle.cc",
|
||||
"handle.h",
|
||||
"handle_close_observer.h",
|
||||
"mojo_runner_delegate.cc",
|
||||
"mojo_runner_delegate.h",
|
||||
"support.cc",
|
||||
"support.h",
|
||||
"threading.cc",
|
||||
"threading.h",
|
||||
"waiting_callback.cc",
|
||||
"waiting_callback.h",
|
||||
]
|
||||
@ -22,15 +26,24 @@ source_set("js") {
|
||||
"//gin",
|
||||
"//v8",
|
||||
]
|
||||
|
||||
deps = [
|
||||
"//mojo/public/cpp/environment",
|
||||
"//mojo/public/cpp/system",
|
||||
]
|
||||
}
|
||||
|
||||
source_set("js_unittests") {
|
||||
testonly = true
|
||||
deps = [
|
||||
"//mojo/edk/test:test_support",
|
||||
]
|
||||
|
||||
sources = [
|
||||
"handle_unittest.cc",
|
||||
]
|
||||
|
||||
deps = [
|
||||
"//mojo/edk/js",
|
||||
"//mojo/edk/test:test_support",
|
||||
"//mojo/public/cpp/system",
|
||||
"//testing/gtest",
|
||||
]
|
||||
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
include_rules = [
|
||||
"+base",
|
||||
"+gin",
|
||||
"+v8",
|
||||
]
|
||||
|
@ -247,69 +247,73 @@ v8::Local<v8::Value> Core::GetModule(v8::Isolate* isolate) {
|
||||
&g_wrapper_info);
|
||||
|
||||
if (templ.IsEmpty()) {
|
||||
templ = gin::ObjectTemplateBuilder(isolate)
|
||||
// TODO(mpcomplete): Should these just be methods on the JS Handle
|
||||
// object?
|
||||
.SetMethod("close", CloseHandle)
|
||||
.SetMethod("wait", WaitHandle)
|
||||
.SetMethod("waitMany", WaitMany)
|
||||
.SetMethod("createMessagePipe", CreateMessagePipe)
|
||||
.SetMethod("writeMessage", WriteMessage)
|
||||
.SetMethod("readMessage", ReadMessage)
|
||||
.SetMethod("createDataPipe", CreateDataPipe)
|
||||
.SetMethod("writeData", WriteData)
|
||||
.SetMethod("readData", ReadData)
|
||||
.SetMethod("drainData", DoDrainData)
|
||||
templ =
|
||||
gin::ObjectTemplateBuilder(isolate)
|
||||
// TODO(mpcomplete): Should these just be methods on the JS Handle
|
||||
// object?
|
||||
.SetMethod("close", CloseHandle)
|
||||
.SetMethod("wait", WaitHandle)
|
||||
.SetMethod("waitMany", WaitMany)
|
||||
.SetMethod("createMessagePipe", CreateMessagePipe)
|
||||
.SetMethod("writeMessage", WriteMessage)
|
||||
.SetMethod("readMessage", ReadMessage)
|
||||
.SetMethod("createDataPipe", CreateDataPipe)
|
||||
.SetMethod("writeData", WriteData)
|
||||
.SetMethod("readData", ReadData)
|
||||
.SetMethod("drainData", DoDrainData)
|
||||
|
||||
.SetValue("RESULT_OK", MOJO_RESULT_OK)
|
||||
.SetValue("RESULT_CANCELLED", MOJO_RESULT_CANCELLED)
|
||||
.SetValue("RESULT_UNKNOWN", MOJO_RESULT_UNKNOWN)
|
||||
.SetValue("RESULT_INVALID_ARGUMENT", MOJO_RESULT_INVALID_ARGUMENT)
|
||||
.SetValue("RESULT_DEADLINE_EXCEEDED", MOJO_RESULT_DEADLINE_EXCEEDED)
|
||||
.SetValue("RESULT_NOT_FOUND", MOJO_RESULT_NOT_FOUND)
|
||||
.SetValue("RESULT_ALREADY_EXISTS", MOJO_RESULT_ALREADY_EXISTS)
|
||||
.SetValue("RESULT_PERMISSION_DENIED", MOJO_RESULT_PERMISSION_DENIED)
|
||||
.SetValue("RESULT_RESOURCE_EXHAUSTED", MOJO_RESULT_RESOURCE_EXHAUSTED)
|
||||
.SetValue("RESULT_FAILED_PRECONDITION", MOJO_RESULT_FAILED_PRECONDITION)
|
||||
.SetValue("RESULT_ABORTED", MOJO_RESULT_ABORTED)
|
||||
.SetValue("RESULT_OUT_OF_RANGE", MOJO_RESULT_OUT_OF_RANGE)
|
||||
.SetValue("RESULT_UNIMPLEMENTED", MOJO_RESULT_UNIMPLEMENTED)
|
||||
.SetValue("RESULT_INTERNAL", MOJO_RESULT_INTERNAL)
|
||||
.SetValue("RESULT_UNAVAILABLE", MOJO_RESULT_UNAVAILABLE)
|
||||
.SetValue("RESULT_DATA_LOSS", MOJO_RESULT_DATA_LOSS)
|
||||
.SetValue("RESULT_BUSY", MOJO_RESULT_BUSY)
|
||||
.SetValue("RESULT_SHOULD_WAIT", MOJO_RESULT_SHOULD_WAIT)
|
||||
.SetValue("RESULT_OK", MOJO_RESULT_OK)
|
||||
.SetValue("RESULT_CANCELLED", MOJO_RESULT_CANCELLED)
|
||||
.SetValue("RESULT_UNKNOWN", MOJO_RESULT_UNKNOWN)
|
||||
.SetValue("RESULT_INVALID_ARGUMENT", MOJO_RESULT_INVALID_ARGUMENT)
|
||||
.SetValue("RESULT_DEADLINE_EXCEEDED", MOJO_RESULT_DEADLINE_EXCEEDED)
|
||||
.SetValue("RESULT_NOT_FOUND", MOJO_RESULT_NOT_FOUND)
|
||||
.SetValue("RESULT_ALREADY_EXISTS", MOJO_RESULT_ALREADY_EXISTS)
|
||||
.SetValue("RESULT_PERMISSION_DENIED", MOJO_RESULT_PERMISSION_DENIED)
|
||||
.SetValue("RESULT_RESOURCE_EXHAUSTED",
|
||||
MOJO_RESULT_RESOURCE_EXHAUSTED)
|
||||
.SetValue("RESULT_FAILED_PRECONDITION",
|
||||
MOJO_RESULT_FAILED_PRECONDITION)
|
||||
.SetValue("RESULT_ABORTED", MOJO_RESULT_ABORTED)
|
||||
.SetValue("RESULT_OUT_OF_RANGE", MOJO_RESULT_OUT_OF_RANGE)
|
||||
.SetValue("RESULT_UNIMPLEMENTED", MOJO_RESULT_UNIMPLEMENTED)
|
||||
.SetValue("RESULT_INTERNAL", MOJO_RESULT_INTERNAL)
|
||||
.SetValue("RESULT_UNAVAILABLE", MOJO_RESULT_UNAVAILABLE)
|
||||
.SetValue("RESULT_DATA_LOSS", MOJO_RESULT_DATA_LOSS)
|
||||
.SetValue("RESULT_BUSY", MOJO_RESULT_BUSY)
|
||||
.SetValue("RESULT_SHOULD_WAIT", MOJO_RESULT_SHOULD_WAIT)
|
||||
|
||||
.SetValue("DEADLINE_INDEFINITE", MOJO_DEADLINE_INDEFINITE)
|
||||
.SetValue("DEADLINE_INDEFINITE", MOJO_DEADLINE_INDEFINITE)
|
||||
|
||||
.SetValue("HANDLE_SIGNAL_NONE", MOJO_HANDLE_SIGNAL_NONE)
|
||||
.SetValue("HANDLE_SIGNAL_READABLE", MOJO_HANDLE_SIGNAL_READABLE)
|
||||
.SetValue("HANDLE_SIGNAL_WRITABLE", MOJO_HANDLE_SIGNAL_WRITABLE)
|
||||
.SetValue("HANDLE_SIGNAL_NONE", MOJO_HANDLE_SIGNAL_NONE)
|
||||
.SetValue("HANDLE_SIGNAL_READABLE", MOJO_HANDLE_SIGNAL_READABLE)
|
||||
.SetValue("HANDLE_SIGNAL_WRITABLE", MOJO_HANDLE_SIGNAL_WRITABLE)
|
||||
|
||||
.SetValue("CREATE_MESSAGE_PIPE_OPTIONS_FLAG_NONE",
|
||||
MOJO_CREATE_MESSAGE_PIPE_OPTIONS_FLAG_NONE)
|
||||
.SetValue("CREATE_MESSAGE_PIPE_OPTIONS_FLAG_NONE",
|
||||
MOJO_CREATE_MESSAGE_PIPE_OPTIONS_FLAG_NONE)
|
||||
|
||||
.SetValue("WRITE_MESSAGE_FLAG_NONE", MOJO_WRITE_MESSAGE_FLAG_NONE)
|
||||
.SetValue("WRITE_MESSAGE_FLAG_NONE", MOJO_WRITE_MESSAGE_FLAG_NONE)
|
||||
|
||||
.SetValue("READ_MESSAGE_FLAG_NONE", MOJO_READ_MESSAGE_FLAG_NONE)
|
||||
.SetValue("READ_MESSAGE_FLAG_MAY_DISCARD",
|
||||
MOJO_READ_MESSAGE_FLAG_MAY_DISCARD)
|
||||
.SetValue("READ_MESSAGE_FLAG_NONE", MOJO_READ_MESSAGE_FLAG_NONE)
|
||||
.SetValue("READ_MESSAGE_FLAG_MAY_DISCARD",
|
||||
MOJO_READ_MESSAGE_FLAG_MAY_DISCARD)
|
||||
|
||||
.SetValue("CREATE_DATA_PIPE_OPTIONS_FLAG_NONE",
|
||||
MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE)
|
||||
.SetValue("CREATE_DATA_PIPE_OPTIONS_FLAG_MAY_DISCARD",
|
||||
MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_MAY_DISCARD)
|
||||
.SetValue("CREATE_DATA_PIPE_OPTIONS_FLAG_NONE",
|
||||
MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE)
|
||||
.SetValue("CREATE_DATA_PIPE_OPTIONS_FLAG_MAY_DISCARD",
|
||||
MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_MAY_DISCARD)
|
||||
|
||||
.SetValue("WRITE_DATA_FLAG_NONE", MOJO_WRITE_DATA_FLAG_NONE)
|
||||
.SetValue("WRITE_DATA_FLAG_ALL_OR_NONE",
|
||||
MOJO_WRITE_DATA_FLAG_ALL_OR_NONE)
|
||||
.SetValue("WRITE_DATA_FLAG_NONE", MOJO_WRITE_DATA_FLAG_NONE)
|
||||
.SetValue("WRITE_DATA_FLAG_ALL_OR_NONE",
|
||||
MOJO_WRITE_DATA_FLAG_ALL_OR_NONE)
|
||||
|
||||
.SetValue("READ_DATA_FLAG_NONE", MOJO_READ_DATA_FLAG_NONE)
|
||||
.SetValue("READ_DATA_FLAG_ALL_OR_NONE",
|
||||
MOJO_READ_DATA_FLAG_ALL_OR_NONE)
|
||||
.SetValue("READ_DATA_FLAG_DISCARD", MOJO_READ_DATA_FLAG_DISCARD)
|
||||
.SetValue("READ_DATA_FLAG_QUERY", MOJO_READ_DATA_FLAG_QUERY)
|
||||
.Build();
|
||||
.SetValue("READ_DATA_FLAG_NONE", MOJO_READ_DATA_FLAG_NONE)
|
||||
.SetValue("READ_DATA_FLAG_ALL_OR_NONE",
|
||||
MOJO_READ_DATA_FLAG_ALL_OR_NONE)
|
||||
.SetValue("READ_DATA_FLAG_DISCARD", MOJO_READ_DATA_FLAG_DISCARD)
|
||||
.SetValue("READ_DATA_FLAG_QUERY", MOJO_READ_DATA_FLAG_QUERY)
|
||||
.SetValue("READ_DATA_FLAG_PEEK", MOJO_READ_DATA_FLAG_PEEK)
|
||||
.Build();
|
||||
|
||||
data->SetObjectTemplate(&g_wrapper_info, templ);
|
||||
}
|
||||
|
@ -2,8 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef MOJO_BINDINGS_JS_CORE_H_
|
||||
#define MOJO_BINDINGS_JS_CORE_H_
|
||||
#ifndef MOJO_EDK_JS_CORE_H_
|
||||
#define MOJO_EDK_JS_CORE_H_
|
||||
|
||||
#include "v8/include/v8.h"
|
||||
|
||||
@ -19,4 +19,4 @@ class Core {
|
||||
} // namespace js
|
||||
} // namespace mojo
|
||||
|
||||
#endif // MOJO_BINDINGS_JS_CORE_H_
|
||||
#endif // MOJO_EDK_JS_CORE_H_
|
||||
|
@ -2,8 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef MOJO_BINDINGS_JS_DRAIN_DATA_H_
|
||||
#define MOJO_BINDINGS_JS_DRAIN_DATA_H_
|
||||
#ifndef MOJO_EDK_JS_DRAIN_DATA_H_
|
||||
#define MOJO_EDK_JS_DRAIN_DATA_H_
|
||||
|
||||
#include "base/memory/scoped_vector.h"
|
||||
#include "gin/runner.h"
|
||||
@ -61,4 +61,4 @@ class DrainData {
|
||||
} // namespace js
|
||||
} // namespace mojo
|
||||
|
||||
#endif // MOJO_BINDINGS_JS_DRAIN_DATA_H_
|
||||
#endif // MOJO_EDK_JS_DRAIN_DATA_H_
|
||||
|
@ -4,7 +4,6 @@
|
||||
|
||||
#include "mojo/edk/js/handle.h"
|
||||
|
||||
#include <sstream>
|
||||
#include "mojo/edk/js/handle_close_observer.h"
|
||||
|
||||
namespace mojo {
|
||||
@ -20,23 +19,6 @@ HandleWrapper::~HandleWrapper() {
|
||||
NotifyCloseObservers();
|
||||
}
|
||||
|
||||
std::string HandleWrapper::ToString() {
|
||||
std::ostringstream oss;
|
||||
oss << "[mojo::Handle ";
|
||||
if (handle_.is_valid())
|
||||
oss << handle_.get().value();
|
||||
else
|
||||
oss << "null";
|
||||
oss << "]";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
gin::ObjectTemplateBuilder HandleWrapper::GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) {
|
||||
return Wrappable<HandleWrapper>::GetObjectTemplateBuilder(isolate)
|
||||
.SetMethod("toString", &HandleWrapper::ToString);
|
||||
}
|
||||
|
||||
void HandleWrapper::Close() {
|
||||
NotifyCloseObservers();
|
||||
handle_.reset();
|
||||
|
@ -2,13 +2,12 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef MOJO_BINDINGS_JS_HANDLE_H_
|
||||
#define MOJO_BINDINGS_JS_HANDLE_H_
|
||||
#ifndef MOJO_EDK_JS_HANDLE_H_
|
||||
#define MOJO_EDK_JS_HANDLE_H_
|
||||
|
||||
#include "base/observer_list.h"
|
||||
#include "gin/converter.h"
|
||||
#include "gin/handle.h"
|
||||
#include "gin/object_template_builder.h"
|
||||
#include "gin/wrappable.h"
|
||||
#include "mojo/public/cpp/system/core.h"
|
||||
|
||||
@ -27,11 +26,6 @@ class HandleWrapper : public gin::Wrappable<HandleWrapper> {
|
||||
return gin::CreateHandle(isolate, new HandleWrapper(handle));
|
||||
}
|
||||
|
||||
std::string ToString();
|
||||
|
||||
gin::ObjectTemplateBuilder GetObjectTemplateBuilder(v8::Isolate* isolate)
|
||||
override;
|
||||
|
||||
mojo::Handle get() const { return handle_.get(); }
|
||||
mojo::Handle release() { return handle_.release(); }
|
||||
void Close();
|
||||
@ -101,4 +95,4 @@ struct Converter<gin::Handle<mojo::js::HandleWrapper> > {
|
||||
|
||||
} // namespace gin
|
||||
|
||||
#endif // MOJO_BINDINGS_JS_HANDLE_H_
|
||||
#endif // MOJO_EDK_JS_HANDLE_H_
|
||||
|
@ -2,8 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef MOJO_BINDINGS_JS_HANDLE_CLOSE_OBSERVER_H_
|
||||
#define MOJO_BINDINGS_JS_HANDLE_CLOSE_OBSERVER_H_
|
||||
#ifndef MOJO_EDK_JS_HANDLE_CLOSE_OBSERVER_H_
|
||||
#define MOJO_EDK_JS_HANDLE_CLOSE_OBSERVER_H_
|
||||
|
||||
namespace mojo {
|
||||
namespace js {
|
||||
@ -19,4 +19,4 @@ class HandleCloseObserver {
|
||||
} // namespace js
|
||||
} // namespace mojo
|
||||
|
||||
#endif // MOJO_BINDINGS_JS_HANDLE_CLOSE_OBSERVER_H_
|
||||
#endif // MOJO_EDK_JS_HANDLE_CLOSE_OBSERVER_H_
|
||||
|
78
mojo/edk/js/mojo_runner_delegate.cc
Normal file
78
mojo/edk/js/mojo_runner_delegate.cc
Normal file
@ -0,0 +1,78 @@
|
||||
// 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/edk/js/mojo_runner_delegate.h"
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "base/path_service.h"
|
||||
#include "gin/converter.h"
|
||||
#include "gin/modules/console.h"
|
||||
#include "gin/modules/module_registry.h"
|
||||
#include "gin/modules/timer.h"
|
||||
#include "gin/try_catch.h"
|
||||
#include "mojo/edk/js/core.h"
|
||||
#include "mojo/edk/js/handle.h"
|
||||
#include "mojo/edk/js/support.h"
|
||||
#include "mojo/edk/js/threading.h"
|
||||
|
||||
namespace mojo {
|
||||
namespace js {
|
||||
|
||||
namespace {
|
||||
|
||||
// TODO(abarth): Rather than loading these modules from the file system, we
|
||||
// should load them from the network via Mojo IPC.
|
||||
std::vector<base::FilePath> GetModuleSearchPaths() {
|
||||
std::vector<base::FilePath> search_paths(2);
|
||||
PathService::Get(base::DIR_SOURCE_ROOT, &search_paths[0]);
|
||||
PathService::Get(base::DIR_EXE, &search_paths[1]);
|
||||
search_paths[1] = search_paths[1].AppendASCII("gen");
|
||||
return search_paths;
|
||||
}
|
||||
|
||||
void StartCallback(base::WeakPtr<gin::Runner> runner,
|
||||
MojoHandle pipe,
|
||||
v8::Handle<v8::Value> module) {
|
||||
v8::Isolate* isolate = runner->GetContextHolder()->isolate();
|
||||
v8::Handle<v8::Function> start;
|
||||
CHECK(gin::ConvertFromV8(isolate, module, &start));
|
||||
|
||||
v8::Handle<v8::Value> args[] = {
|
||||
gin::ConvertToV8(isolate, Handle(pipe)) };
|
||||
runner->Call(start, runner->global(), 1, args);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
MojoRunnerDelegate::MojoRunnerDelegate()
|
||||
: ModuleRunnerDelegate(GetModuleSearchPaths()) {
|
||||
AddBuiltinModule(gin::Console::kModuleName, gin::Console::GetModule);
|
||||
AddBuiltinModule(gin::TimerModule::kName, gin::TimerModule::GetModule);
|
||||
AddBuiltinModule(js::Core::kModuleName, js::Core::GetModule);
|
||||
AddBuiltinModule(js::Support::kModuleName, js::Support::GetModule);
|
||||
AddBuiltinModule(js::Threading::kModuleName, js::Threading::GetModule);
|
||||
}
|
||||
|
||||
MojoRunnerDelegate::~MojoRunnerDelegate() {
|
||||
}
|
||||
|
||||
void MojoRunnerDelegate::Start(gin::Runner* runner,
|
||||
MojoHandle pipe,
|
||||
const std::string& module) {
|
||||
gin::Runner::Scope scope(runner);
|
||||
gin::ModuleRegistry* registry =
|
||||
gin::ModuleRegistry::From(runner->GetContextHolder()->context());
|
||||
registry->LoadModule(runner->GetContextHolder()->isolate(), module,
|
||||
base::Bind(StartCallback, runner->GetWeakPtr(), pipe));
|
||||
AttemptToLoadMoreModules(runner);
|
||||
}
|
||||
|
||||
void MojoRunnerDelegate::UnhandledException(gin::ShellRunner* runner,
|
||||
gin::TryCatch& try_catch) {
|
||||
gin::ModuleRunnerDelegate::UnhandledException(runner, try_catch);
|
||||
LOG(ERROR) << try_catch.GetStackTrace();
|
||||
}
|
||||
|
||||
} // namespace js
|
||||
} // namespace mojo
|
33
mojo/edk/js/mojo_runner_delegate.h
Normal file
33
mojo/edk/js/mojo_runner_delegate.h
Normal file
@ -0,0 +1,33 @@
|
||||
// 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_EDK_JS_MOJO_RUNNER_DELEGATE_H_
|
||||
#define MOJO_EDK_JS_MOJO_RUNNER_DELEGATE_H_
|
||||
|
||||
#include "base/macros.h"
|
||||
#include "gin/modules/module_runner_delegate.h"
|
||||
#include "mojo/public/c/system/core.h"
|
||||
|
||||
namespace mojo {
|
||||
namespace js {
|
||||
|
||||
class MojoRunnerDelegate : public gin::ModuleRunnerDelegate {
|
||||
public:
|
||||
MojoRunnerDelegate();
|
||||
~MojoRunnerDelegate() override;
|
||||
|
||||
void Start(gin::Runner* runner, MojoHandle pipe, const std::string& module);
|
||||
|
||||
private:
|
||||
// From ModuleRunnerDelegate:
|
||||
void UnhandledException(gin::ShellRunner* runner,
|
||||
gin::TryCatch& try_catch) override;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(MojoRunnerDelegate);
|
||||
};
|
||||
|
||||
} // namespace js
|
||||
} // namespace mojo
|
||||
|
||||
#endif // MOJO_EDK_JS_MOJO_RUNNER_DELEGATE_H_
|
@ -2,8 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef MOJO_BINDINGS_JS_SUPPORT_H_
|
||||
#define MOJO_BINDINGS_JS_SUPPORT_H_
|
||||
#ifndef MOJO_EDK_JS_SUPPORT_H_
|
||||
#define MOJO_EDK_JS_SUPPORT_H_
|
||||
|
||||
#include "v8/include/v8.h"
|
||||
|
||||
@ -19,4 +19,4 @@ class Support {
|
||||
} // namespace js
|
||||
} // namespace mojo
|
||||
|
||||
#endif // MOJO_BINDINGS_JS_SUPPORT_H_
|
||||
#endif // MOJO_EDK_JS_SUPPORT_H_
|
||||
|
39
mojo/edk/js/test/BUILD.gn
Normal file
39
mojo/edk/js/test/BUILD.gn
Normal file
@ -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.
|
||||
|
||||
test("js_unittests") {
|
||||
deps = [
|
||||
"//base",
|
||||
"//gin:gin_test",
|
||||
"//mojo/edk/js",
|
||||
"//mojo/edk/js:js_unittests",
|
||||
"//mojo/edk/test:run_all_unittests",
|
||||
"//mojo/edk/test:test_support",
|
||||
"//mojo/public/cpp/environment",
|
||||
"//mojo/public/cpp/system",
|
||||
"//mojo/public/cpp/utility",
|
||||
"//mojo/environment:chromium",
|
||||
"//mojo/public/interfaces/bindings/tests:test_interfaces",
|
||||
]
|
||||
|
||||
sources = [ "run_js_tests.cc" ]
|
||||
}
|
||||
|
||||
test("js_integration_tests") {
|
||||
deps = [
|
||||
"//base",
|
||||
"//gin:gin_test",
|
||||
"//mojo/edk/js",
|
||||
"//mojo/edk/js/tests:js_to_cpp_tests",
|
||||
"//mojo/edk/test:run_all_unittests",
|
||||
"//mojo/edk/test:test_support",
|
||||
"//mojo/public/cpp/bindings",
|
||||
"//mojo/environment:chromium",
|
||||
"//mojo/public/interfaces/bindings/tests:test_interfaces",
|
||||
]
|
||||
|
||||
sources = [
|
||||
"run_js_integration_tests.cc"
|
||||
]
|
||||
}
|
34
mojo/edk/js/test/hexdump.js
Normal file
34
mojo/edk/js/test/hexdump.js
Normal file
@ -0,0 +1,34 @@
|
||||
// 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.
|
||||
|
||||
define(function() {
|
||||
function hexify(value, length) {
|
||||
var hex = value.toString(16);
|
||||
while (hex.length < length)
|
||||
hex = "0" + hex;
|
||||
return hex;
|
||||
}
|
||||
|
||||
function dumpArray(bytes) {
|
||||
var dumped = "";
|
||||
for (var i = 0; i < bytes.length; ++i) {
|
||||
dumped += hexify(bytes[i], 2);
|
||||
|
||||
if (i % 16 == 15) {
|
||||
dumped += "\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
if (i % 2 == 1)
|
||||
dumped += " ";
|
||||
if (i % 8 == 7)
|
||||
dumped += " ";
|
||||
}
|
||||
return dumped;
|
||||
}
|
||||
|
||||
var exports = {};
|
||||
exports.dumpArray = dumpArray;
|
||||
return exports;
|
||||
});
|
57
mojo/edk/js/test/run_js_integration_tests.cc
Normal file
57
mojo/edk/js/test/run_js_integration_tests.cc
Normal file
@ -0,0 +1,57 @@
|
||||
// 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/files/file_path.h"
|
||||
#include "base/path_service.h"
|
||||
#include "gin/modules/console.h"
|
||||
#include "gin/modules/module_registry.h"
|
||||
#include "gin/modules/timer.h"
|
||||
#include "gin/test/file_runner.h"
|
||||
#include "gin/test/gtest.h"
|
||||
#include "mojo/edk/js/core.h"
|
||||
#include "mojo/edk/js/support.h"
|
||||
#include "mojo/edk/js/threading.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
namespace mojo {
|
||||
namespace js {
|
||||
namespace {
|
||||
|
||||
class TestRunnerDelegate : public gin::FileRunnerDelegate {
|
||||
public:
|
||||
TestRunnerDelegate() {
|
||||
AddBuiltinModule(gin::Console::kModuleName, gin::Console::GetModule);
|
||||
AddBuiltinModule(Core::kModuleName, Core::GetModule);
|
||||
AddBuiltinModule(gin::TimerModule::kName, gin::TimerModule::GetModule);
|
||||
AddBuiltinModule(Threading::kModuleName, Threading::GetModule);
|
||||
}
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(TestRunnerDelegate);
|
||||
};
|
||||
|
||||
void RunTest(std::string test, bool addSupportModule) {
|
||||
base::FilePath path;
|
||||
PathService::Get(base::DIR_SOURCE_ROOT, &path);
|
||||
path = path.AppendASCII("mojo")
|
||||
.AppendASCII("edk")
|
||||
.AppendASCII("js")
|
||||
.AppendASCII("tests")
|
||||
.AppendASCII(test);
|
||||
TestRunnerDelegate delegate;
|
||||
if (addSupportModule)
|
||||
delegate.AddBuiltinModule(Support::kModuleName, Support::GetModule);
|
||||
gin::RunTestFromFile(path, &delegate, true);
|
||||
}
|
||||
|
||||
TEST(JSTest, connection) {
|
||||
RunTest("connection_tests.js", false);
|
||||
}
|
||||
|
||||
TEST(JSTest, sample_service) {
|
||||
RunTest("sample_service_tests.js", true);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace js
|
||||
} // namespace mojo
|
@ -6,7 +6,6 @@
|
||||
#include "base/path_service.h"
|
||||
#include "gin/modules/console.h"
|
||||
#include "gin/modules/module_registry.h"
|
||||
#include "gin/modules/timer.h"
|
||||
#include "gin/test/file_runner.h"
|
||||
#include "gin/test/gtest.h"
|
||||
#include "mojo/edk/js/core.h"
|
||||
@ -31,7 +30,6 @@ class TestRunnerDelegate : public gin::FileRunnerDelegate {
|
||||
};
|
||||
|
||||
void RunTest(std::string test, bool run_until_idle) {
|
||||
Environment env;
|
||||
base::FilePath path;
|
||||
PathService::Get(base::DIR_SOURCE_ROOT, &path);
|
||||
path = path.AppendASCII("mojo")
|
@ -2,17 +2,26 @@
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
test("js_unittests") {
|
||||
import("//mojo/public/tools/bindings/mojom.gni")
|
||||
|
||||
source_set("js_to_cpp_tests") {
|
||||
testonly = true
|
||||
|
||||
deps = [
|
||||
":js_to_cpp_bindings",
|
||||
"//gin:gin_test",
|
||||
"//mojo/edk/js",
|
||||
"//mojo/edk/js:js_unittests",
|
||||
"//mojo/edk/test:run_all_unittests",
|
||||
"//mojo/edk/test:test_support",
|
||||
"//mojo/public/cpp/environment:standalone",
|
||||
"//mojo/public/cpp/utility",
|
||||
"//mojo/public/cpp/bindings",
|
||||
"//mojo/public/cpp/system",
|
||||
"//mojo/public/interfaces/bindings/tests:test_interfaces",
|
||||
]
|
||||
|
||||
sources = [ "run_js_tests.cc" ]
|
||||
sources = [
|
||||
"js_to_cpp_tests.cc",
|
||||
]
|
||||
}
|
||||
|
||||
mojom("js_to_cpp_bindings") {
|
||||
sources = [ "js_to_cpp.mojom" ]
|
||||
}
|
||||
|
@ -1,7 +0,0 @@
|
||||
include_rules = [
|
||||
"+base",
|
||||
"+gin",
|
||||
"+v8",
|
||||
"+mojo/edk/js/core.h",
|
||||
"+mojo/edk/js/support.h",
|
||||
]
|
261
mojo/edk/js/tests/connection_tests.js
Normal file
261
mojo/edk/js/tests/connection_tests.js
Normal file
@ -0,0 +1,261 @@
|
||||
// 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.
|
||||
|
||||
// Mock out the support module to avoid depending on the message loop.
|
||||
define("mojo/public/js/support", ["timer"], function(timer) {
|
||||
var waitingCallbacks = [];
|
||||
|
||||
function WaitCookie(id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
function asyncWait(handle, flags, callback) {
|
||||
var id = waitingCallbacks.length;
|
||||
waitingCallbacks.push(callback);
|
||||
return new WaitCookie(id);
|
||||
}
|
||||
|
||||
function cancelWait(cookie) {
|
||||
waitingCallbacks[cookie.id] = null;
|
||||
}
|
||||
|
||||
function numberOfWaitingCallbacks() {
|
||||
var count = 0;
|
||||
for (var i = 0; i < waitingCallbacks.length; ++i) {
|
||||
if (waitingCallbacks[i])
|
||||
++count;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
function pumpOnce(result) {
|
||||
var callbacks = waitingCallbacks;
|
||||
waitingCallbacks = [];
|
||||
for (var i = 0; i < callbacks.length; ++i) {
|
||||
if (callbacks[i])
|
||||
callbacks[i](result);
|
||||
}
|
||||
}
|
||||
|
||||
// Queue up a pumpOnce call to execute after the stack unwinds. Use
|
||||
// this to trigger a pump after all Promises are executed.
|
||||
function queuePump(result) {
|
||||
timer.createOneShot(0, pumpOnce.bind(undefined, result));
|
||||
}
|
||||
|
||||
var exports = {};
|
||||
exports.asyncWait = asyncWait;
|
||||
exports.cancelWait = cancelWait;
|
||||
exports.numberOfWaitingCallbacks = numberOfWaitingCallbacks;
|
||||
exports.pumpOnce = pumpOnce;
|
||||
exports.queuePump = queuePump;
|
||||
return exports;
|
||||
});
|
||||
|
||||
define([
|
||||
"gin/test/expect",
|
||||
"mojo/public/js/support",
|
||||
"mojo/public/js/core",
|
||||
"mojo/public/js/connection",
|
||||
"mojo/public/interfaces/bindings/tests/sample_interfaces.mojom",
|
||||
"mojo/public/interfaces/bindings/tests/sample_service.mojom",
|
||||
"mojo/public/js/threading",
|
||||
"gc",
|
||||
], function(expect,
|
||||
mockSupport,
|
||||
core,
|
||||
connection,
|
||||
sample_interfaces,
|
||||
sample_service,
|
||||
threading,
|
||||
gc) {
|
||||
testClientServer();
|
||||
testWriteToClosedPipe();
|
||||
testRequestResponse().then(function() {
|
||||
this.result = "PASS";
|
||||
gc.collectGarbage(); // should not crash
|
||||
threading.quit();
|
||||
}.bind(this)).catch(function(e) {
|
||||
this.result = "FAIL: " + (e.stack || e);
|
||||
threading.quit();
|
||||
}.bind(this));
|
||||
|
||||
function testClientServer() {
|
||||
var receivedFrobinate = false;
|
||||
var receivedDidFrobinate = false;
|
||||
|
||||
// ServiceImpl ------------------------------------------------------------
|
||||
|
||||
function ServiceImpl(peer) {
|
||||
this.peer = peer;
|
||||
}
|
||||
|
||||
ServiceImpl.prototype = Object.create(
|
||||
sample_service.Service.stubClass.prototype);
|
||||
|
||||
ServiceImpl.prototype.frobinate = function(foo, baz, port) {
|
||||
receivedFrobinate = true;
|
||||
|
||||
expect(foo.name).toBe("Example name");
|
||||
expect(baz).toBeTruthy();
|
||||
expect(core.close(port)).toBe(core.RESULT_OK);
|
||||
|
||||
this.peer.didFrobinate(42);
|
||||
};
|
||||
|
||||
// ServiceClientImpl ------------------------------------------------------
|
||||
|
||||
function ServiceClientImpl(peer) {
|
||||
this.peer = peer;
|
||||
}
|
||||
|
||||
ServiceClientImpl.prototype =
|
||||
Object.create(sample_service.ServiceClient.stubClass.prototype);
|
||||
|
||||
ServiceClientImpl.prototype.didFrobinate = function(result) {
|
||||
receivedDidFrobinate = true;
|
||||
|
||||
expect(result).toBe(42);
|
||||
};
|
||||
|
||||
var pipe = core.createMessagePipe();
|
||||
var anotherPipe = core.createMessagePipe();
|
||||
var sourcePipe = core.createMessagePipe();
|
||||
|
||||
var connection0 = new connection.Connection(
|
||||
pipe.handle0, ServiceImpl, sample_service.ServiceClient.proxyClass);
|
||||
|
||||
var connection1 = new connection.Connection(
|
||||
pipe.handle1, ServiceClientImpl, sample_service.Service.proxyClass);
|
||||
|
||||
var foo = new sample_service.Foo();
|
||||
foo.bar = new sample_service.Bar();
|
||||
foo.name = "Example name";
|
||||
foo.source = sourcePipe.handle0;
|
||||
connection1.remote.frobinate(foo, true, anotherPipe.handle0);
|
||||
|
||||
mockSupport.pumpOnce(core.RESULT_OK);
|
||||
|
||||
expect(receivedFrobinate).toBeTruthy();
|
||||
expect(receivedDidFrobinate).toBeTruthy();
|
||||
|
||||
connection0.close();
|
||||
connection1.close();
|
||||
|
||||
expect(mockSupport.numberOfWaitingCallbacks()).toBe(0);
|
||||
|
||||
// sourcePipe.handle0 was closed automatically when sent over IPC.
|
||||
expect(core.close(sourcePipe.handle0)).toBe(core.RESULT_INVALID_ARGUMENT);
|
||||
// sourcePipe.handle1 hasn't been closed yet.
|
||||
expect(core.close(sourcePipe.handle1)).toBe(core.RESULT_OK);
|
||||
|
||||
// anotherPipe.handle0 was closed automatically when sent over IPC.
|
||||
expect(core.close(anotherPipe.handle0)).toBe(core.RESULT_INVALID_ARGUMENT);
|
||||
// anotherPipe.handle1 hasn't been closed yet.
|
||||
expect(core.close(anotherPipe.handle1)).toBe(core.RESULT_OK);
|
||||
|
||||
// The Connection object is responsible for closing these handles.
|
||||
expect(core.close(pipe.handle0)).toBe(core.RESULT_INVALID_ARGUMENT);
|
||||
expect(core.close(pipe.handle1)).toBe(core.RESULT_INVALID_ARGUMENT);
|
||||
}
|
||||
|
||||
function testWriteToClosedPipe() {
|
||||
var pipe = core.createMessagePipe();
|
||||
|
||||
var connection1 = new connection.Connection(
|
||||
pipe.handle1, function() {}, sample_service.Service.proxyClass);
|
||||
|
||||
// Close the other end of the pipe.
|
||||
core.close(pipe.handle0);
|
||||
|
||||
// Not observed yet because we haven't pumped events yet.
|
||||
expect(connection1.encounteredError()).toBeFalsy();
|
||||
|
||||
var foo = new sample_service.Foo();
|
||||
foo.bar = new sample_service.Bar();
|
||||
// TODO(darin): crbug.com/357043: pass null in place of |foo| here.
|
||||
connection1.remote.frobinate(foo, true, null);
|
||||
|
||||
// Write failures are not reported.
|
||||
expect(connection1.encounteredError()).toBeFalsy();
|
||||
|
||||
// Pump events, and then we should start observing the closed pipe.
|
||||
mockSupport.pumpOnce(core.RESULT_OK);
|
||||
|
||||
expect(connection1.encounteredError()).toBeTruthy();
|
||||
|
||||
connection1.close();
|
||||
}
|
||||
|
||||
function testRequestResponse() {
|
||||
|
||||
// ProviderImpl ------------------------------------------------------------
|
||||
|
||||
function ProviderImpl(peer) {
|
||||
this.peer = peer;
|
||||
}
|
||||
|
||||
ProviderImpl.prototype =
|
||||
Object.create(sample_interfaces.Provider.stubClass.prototype);
|
||||
|
||||
ProviderImpl.prototype.echoString = function(a) {
|
||||
mockSupport.queuePump(core.RESULT_OK);
|
||||
return Promise.resolve({a: a});
|
||||
};
|
||||
|
||||
ProviderImpl.prototype.echoStrings = function(a, b) {
|
||||
mockSupport.queuePump(core.RESULT_OK);
|
||||
return Promise.resolve({a: a, b: b});
|
||||
};
|
||||
|
||||
// ProviderClientImpl ------------------------------------------------------
|
||||
|
||||
function ProviderClientImpl(peer) {
|
||||
this.peer = peer;
|
||||
}
|
||||
|
||||
ProviderClientImpl.prototype =
|
||||
Object.create(sample_interfaces.ProviderClient.stubClass.prototype);
|
||||
|
||||
var pipe = core.createMessagePipe();
|
||||
|
||||
var connection0 = new connection.Connection(
|
||||
pipe.handle0,
|
||||
ProviderImpl,
|
||||
sample_interfaces.ProviderClient.proxyClass);
|
||||
|
||||
var connection1 = new connection.Connection(
|
||||
pipe.handle1,
|
||||
ProviderClientImpl,
|
||||
sample_interfaces.Provider.proxyClass);
|
||||
|
||||
var origReadMessage = core.readMessage;
|
||||
// echoString
|
||||
mockSupport.queuePump(core.RESULT_OK);
|
||||
return connection1.remote.echoString("hello").then(function(response) {
|
||||
expect(response.a).toBe("hello");
|
||||
}).then(function() {
|
||||
// echoStrings
|
||||
mockSupport.queuePump(core.RESULT_OK);
|
||||
return connection1.remote.echoStrings("hello", "world");
|
||||
}).then(function(response) {
|
||||
expect(response.a).toBe("hello");
|
||||
expect(response.b).toBe("world");
|
||||
}).then(function() {
|
||||
// Mock a read failure, expect it to fail.
|
||||
core.readMessage = function() {
|
||||
return { result: core.RESULT_UNKNOWN };
|
||||
};
|
||||
mockSupport.queuePump(core.RESULT_OK);
|
||||
return connection1.remote.echoString("goodbye");
|
||||
}).then(function() {
|
||||
throw Error("Expected echoString to fail.");
|
||||
}, function(error) {
|
||||
expect(error.message).toBe("Connection error: " + core.RESULT_UNKNOWN);
|
||||
|
||||
// Clean up.
|
||||
core.readMessage = origReadMessage;
|
||||
});
|
||||
}
|
||||
});
|
53
mojo/edk/js/tests/js_to_cpp.mojom
Normal file
53
mojo/edk/js/tests/js_to_cpp.mojom
Normal file
@ -0,0 +1,53 @@
|
||||
module js_to_cpp;
|
||||
|
||||
// This struct encompasses all of the basic types, so that they
|
||||
// may be sent from C++ to JS and back for validation.
|
||||
struct EchoArgs {
|
||||
int64 si64;
|
||||
int32 si32;
|
||||
int16 si16;
|
||||
int8 si8;
|
||||
uint64 ui64;
|
||||
uint32 ui32;
|
||||
uint16 ui16;
|
||||
uint8 ui8;
|
||||
float float_val;
|
||||
float float_inf;
|
||||
float float_nan;
|
||||
double double_val;
|
||||
double double_inf;
|
||||
double double_nan;
|
||||
string? name;
|
||||
array<string>? string_array;
|
||||
handle<message_pipe>? message_handle;
|
||||
handle<data_pipe_consumer>? data_handle;
|
||||
};
|
||||
|
||||
struct EchoArgsList {
|
||||
EchoArgsList? next;
|
||||
EchoArgs? item;
|
||||
};
|
||||
|
||||
// Note: For messages which control test flow, pick numbers that are unlikely
|
||||
// to be hit as a result of our deliberate corruption of response messages.
|
||||
interface CppSide {
|
||||
// Sent for all tests to notify that the JS side is now ready.
|
||||
StartTest@88888888();
|
||||
|
||||
// Indicates end for echo, bit-flip, and back-pointer tests.
|
||||
TestFinished@99999999();
|
||||
|
||||
// Responses from specific tests.
|
||||
PingResponse();
|
||||
EchoResponse(EchoArgsList list);
|
||||
BitFlipResponse(EchoArgsList arg);
|
||||
BackPointerResponse(EchoArgsList arg);
|
||||
};
|
||||
|
||||
[Client=CppSide]
|
||||
interface JsSide {
|
||||
Ping();
|
||||
Echo(int32 numIterations, EchoArgs arg);
|
||||
BitFlip(EchoArgs arg);
|
||||
BackPointer(EchoArgs arg);
|
||||
};
|
418
mojo/edk/js/tests/js_to_cpp_tests.cc
Normal file
418
mojo/edk/js/tests/js_to_cpp_tests.cc
Normal file
@ -0,0 +1,418 @@
|
||||
// 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/files/file_path.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/macros.h"
|
||||
#include "base/message_loop/message_loop.h"
|
||||
#include "base/run_loop.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "gin/array_buffer.h"
|
||||
#include "gin/public/isolate_holder.h"
|
||||
#include "mojo/edk/js/mojo_runner_delegate.h"
|
||||
#include "mojo/edk/js/tests/js_to_cpp.mojom.h"
|
||||
#include "mojo/edk/test/test_utils.h"
|
||||
#include "mojo/public/cpp/system/core.h"
|
||||
#include "mojo/public/cpp/system/macros.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
namespace mojo {
|
||||
namespace js {
|
||||
|
||||
// Global value updated by some checks to prevent compilers from optimizing
|
||||
// reads out of existence.
|
||||
uint32 g_waste_accumulator = 0;
|
||||
|
||||
namespace {
|
||||
|
||||
// Negative numbers with different values in each byte, the last of
|
||||
// which can survive promotion to double and back.
|
||||
const int8 kExpectedInt8Value = -65;
|
||||
const int16 kExpectedInt16Value = -16961;
|
||||
const int32 kExpectedInt32Value = -1145258561;
|
||||
const int64 kExpectedInt64Value = -77263311946305LL;
|
||||
|
||||
// Positive numbers with different values in each byte, the last of
|
||||
// which can survive promotion to double and back.
|
||||
const uint8 kExpectedUInt8Value = 65;
|
||||
const uint16 kExpectedUInt16Value = 16961;
|
||||
const uint32 kExpectedUInt32Value = 1145258561;
|
||||
const uint64 kExpectedUInt64Value = 77263311946305LL;
|
||||
|
||||
// Double/float values, including special case constants.
|
||||
const double kExpectedDoubleVal = 3.14159265358979323846;
|
||||
const double kExpectedDoubleInf = std::numeric_limits<double>::infinity();
|
||||
const double kExpectedDoubleNan = std::numeric_limits<double>::quiet_NaN();
|
||||
const float kExpectedFloatVal = static_cast<float>(kExpectedDoubleVal);
|
||||
const float kExpectedFloatInf = std::numeric_limits<float>::infinity();
|
||||
const float kExpectedFloatNan = std::numeric_limits<float>::quiet_NaN();
|
||||
|
||||
// NaN has the property that it is not equal to itself.
|
||||
#define EXPECT_NAN(x) EXPECT_NE(x, x)
|
||||
|
||||
void CheckDataPipe(MojoHandle data_pipe_handle) {
|
||||
unsigned char buffer[100];
|
||||
uint32_t buffer_size = static_cast<uint32_t>(sizeof(buffer));
|
||||
MojoResult result = MojoReadData(
|
||||
data_pipe_handle, buffer, &buffer_size, MOJO_READ_DATA_FLAG_NONE);
|
||||
EXPECT_EQ(MOJO_RESULT_OK, result);
|
||||
EXPECT_EQ(64u, buffer_size);
|
||||
for (int i = 0; i < 64; ++i) {
|
||||
EXPECT_EQ(i, buffer[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void CheckMessagePipe(MojoHandle message_pipe_handle) {
|
||||
unsigned char buffer[100];
|
||||
uint32_t buffer_size = static_cast<uint32_t>(sizeof(buffer));
|
||||
MojoResult result = MojoReadMessage(
|
||||
message_pipe_handle, buffer, &buffer_size, 0, 0, 0);
|
||||
EXPECT_EQ(MOJO_RESULT_OK, result);
|
||||
EXPECT_EQ(64u, buffer_size);
|
||||
for (int i = 0; i < 64; ++i) {
|
||||
EXPECT_EQ(255 - i, buffer[i]);
|
||||
}
|
||||
}
|
||||
|
||||
js_to_cpp::EchoArgsPtr BuildSampleEchoArgs() {
|
||||
js_to_cpp::EchoArgsPtr args(js_to_cpp::EchoArgs::New());
|
||||
args->si64 = kExpectedInt64Value;
|
||||
args->si32 = kExpectedInt32Value;
|
||||
args->si16 = kExpectedInt16Value;
|
||||
args->si8 = kExpectedInt8Value;
|
||||
args->ui64 = kExpectedUInt64Value;
|
||||
args->ui32 = kExpectedUInt32Value;
|
||||
args->ui16 = kExpectedUInt16Value;
|
||||
args->ui8 = kExpectedUInt8Value;
|
||||
args->float_val = kExpectedFloatVal;
|
||||
args->float_inf = kExpectedFloatInf;
|
||||
args->float_nan = kExpectedFloatNan;
|
||||
args->double_val = kExpectedDoubleVal;
|
||||
args->double_inf = kExpectedDoubleInf;
|
||||
args->double_nan = kExpectedDoubleNan;
|
||||
args->name = "coming";
|
||||
Array<String> string_array(3);
|
||||
string_array[0] = "one";
|
||||
string_array[1] = "two";
|
||||
string_array[2] = "three";
|
||||
args->string_array = string_array.Pass();
|
||||
return args.Pass();
|
||||
}
|
||||
|
||||
void CheckSampleEchoArgs(const js_to_cpp::EchoArgs& arg) {
|
||||
EXPECT_EQ(kExpectedInt64Value, arg.si64);
|
||||
EXPECT_EQ(kExpectedInt32Value, arg.si32);
|
||||
EXPECT_EQ(kExpectedInt16Value, arg.si16);
|
||||
EXPECT_EQ(kExpectedInt8Value, arg.si8);
|
||||
EXPECT_EQ(kExpectedUInt64Value, arg.ui64);
|
||||
EXPECT_EQ(kExpectedUInt32Value, arg.ui32);
|
||||
EXPECT_EQ(kExpectedUInt16Value, arg.ui16);
|
||||
EXPECT_EQ(kExpectedUInt8Value, arg.ui8);
|
||||
EXPECT_EQ(kExpectedFloatVal, arg.float_val);
|
||||
EXPECT_EQ(kExpectedFloatInf, arg.float_inf);
|
||||
EXPECT_NAN(arg.float_nan);
|
||||
EXPECT_EQ(kExpectedDoubleVal, arg.double_val);
|
||||
EXPECT_EQ(kExpectedDoubleInf, arg.double_inf);
|
||||
EXPECT_NAN(arg.double_nan);
|
||||
EXPECT_EQ(std::string("coming"), arg.name.get());
|
||||
EXPECT_EQ(std::string("one"), arg.string_array[0].get());
|
||||
EXPECT_EQ(std::string("two"), arg.string_array[1].get());
|
||||
EXPECT_EQ(std::string("three"), arg.string_array[2].get());
|
||||
CheckDataPipe(arg.data_handle.get().value());
|
||||
CheckMessagePipe(arg.message_handle.get().value());
|
||||
}
|
||||
|
||||
void CheckSampleEchoArgsList(const js_to_cpp::EchoArgsListPtr& list) {
|
||||
if (list.is_null())
|
||||
return;
|
||||
CheckSampleEchoArgs(*list->item);
|
||||
CheckSampleEchoArgsList(list->next);
|
||||
}
|
||||
|
||||
// More forgiving checks are needed in the face of potentially corrupt
|
||||
// messages. The values don't matter so long as all accesses are within
|
||||
// bounds.
|
||||
void CheckCorruptedString(const String& arg) {
|
||||
if (arg.is_null())
|
||||
return;
|
||||
for (size_t i = 0; i < arg.size(); ++i)
|
||||
g_waste_accumulator += arg[i];
|
||||
}
|
||||
|
||||
void CheckCorruptedStringArray(const Array<String>& string_array) {
|
||||
if (string_array.is_null())
|
||||
return;
|
||||
for (size_t i = 0; i < string_array.size(); ++i)
|
||||
CheckCorruptedString(string_array[i]);
|
||||
}
|
||||
|
||||
void CheckCorruptedDataPipe(MojoHandle data_pipe_handle) {
|
||||
unsigned char buffer[100];
|
||||
uint32_t buffer_size = static_cast<uint32_t>(sizeof(buffer));
|
||||
MojoResult result = MojoReadData(
|
||||
data_pipe_handle, buffer, &buffer_size, MOJO_READ_DATA_FLAG_NONE);
|
||||
if (result != MOJO_RESULT_OK)
|
||||
return;
|
||||
for (uint32_t i = 0; i < buffer_size; ++i)
|
||||
g_waste_accumulator += buffer[i];
|
||||
}
|
||||
|
||||
void CheckCorruptedMessagePipe(MojoHandle message_pipe_handle) {
|
||||
unsigned char buffer[100];
|
||||
uint32_t buffer_size = static_cast<uint32_t>(sizeof(buffer));
|
||||
MojoResult result = MojoReadMessage(
|
||||
message_pipe_handle, buffer, &buffer_size, 0, 0, 0);
|
||||
if (result != MOJO_RESULT_OK)
|
||||
return;
|
||||
for (uint32_t i = 0; i < buffer_size; ++i)
|
||||
g_waste_accumulator += buffer[i];
|
||||
}
|
||||
|
||||
void CheckCorruptedEchoArgs(const js_to_cpp::EchoArgsPtr& arg) {
|
||||
if (arg.is_null())
|
||||
return;
|
||||
CheckCorruptedString(arg->name);
|
||||
CheckCorruptedStringArray(arg->string_array);
|
||||
if (arg->data_handle.is_valid())
|
||||
CheckCorruptedDataPipe(arg->data_handle.get().value());
|
||||
if (arg->message_handle.is_valid())
|
||||
CheckCorruptedMessagePipe(arg->message_handle.get().value());
|
||||
}
|
||||
|
||||
void CheckCorruptedEchoArgsList(const js_to_cpp::EchoArgsListPtr& list) {
|
||||
if (list.is_null())
|
||||
return;
|
||||
CheckCorruptedEchoArgs(list->item);
|
||||
CheckCorruptedEchoArgsList(list->next);
|
||||
}
|
||||
|
||||
// Base Provider implementation class. It's expected that tests subclass and
|
||||
// override the appropriate Provider functions. When test is done quit the
|
||||
// run_loop().
|
||||
class CppSideConnection : public js_to_cpp::CppSide {
|
||||
public:
|
||||
CppSideConnection() :
|
||||
run_loop_(NULL),
|
||||
js_side_(NULL),
|
||||
mishandled_messages_(0) {
|
||||
}
|
||||
~CppSideConnection() override {}
|
||||
|
||||
void set_run_loop(base::RunLoop* run_loop) { run_loop_ = run_loop; }
|
||||
base::RunLoop* run_loop() { return run_loop_; }
|
||||
|
||||
void set_js_side(js_to_cpp::JsSide* js_side) { js_side_ = js_side; }
|
||||
js_to_cpp::JsSide* js_side() { return js_side_; }
|
||||
|
||||
// js_to_cpp::CppSide:
|
||||
void StartTest() override { NOTREACHED(); }
|
||||
|
||||
void TestFinished() override { NOTREACHED(); }
|
||||
|
||||
void PingResponse() override { mishandled_messages_ += 1; }
|
||||
|
||||
void EchoResponse(js_to_cpp::EchoArgsListPtr list) override {
|
||||
mishandled_messages_ += 1;
|
||||
}
|
||||
|
||||
void BitFlipResponse(js_to_cpp::EchoArgsListPtr list) override {
|
||||
mishandled_messages_ += 1;
|
||||
}
|
||||
|
||||
void BackPointerResponse(js_to_cpp::EchoArgsListPtr list) override {
|
||||
mishandled_messages_ += 1;
|
||||
}
|
||||
|
||||
protected:
|
||||
base::RunLoop* run_loop_;
|
||||
js_to_cpp::JsSide* js_side_;
|
||||
int mishandled_messages_;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(CppSideConnection);
|
||||
};
|
||||
|
||||
// Trivial test to verify a message sent from JS is received.
|
||||
class PingCppSideConnection : public CppSideConnection {
|
||||
public:
|
||||
PingCppSideConnection() : got_message_(false) {}
|
||||
~PingCppSideConnection() override {}
|
||||
|
||||
// js_to_cpp::CppSide:
|
||||
void StartTest() override { js_side_->Ping(); }
|
||||
|
||||
void PingResponse() override {
|
||||
got_message_ = true;
|
||||
run_loop()->Quit();
|
||||
}
|
||||
|
||||
bool DidSucceed() {
|
||||
return got_message_ && !mishandled_messages_;
|
||||
}
|
||||
|
||||
private:
|
||||
bool got_message_;
|
||||
DISALLOW_COPY_AND_ASSIGN(PingCppSideConnection);
|
||||
};
|
||||
|
||||
// Test that parameters are passed with correct values.
|
||||
class EchoCppSideConnection : public CppSideConnection {
|
||||
public:
|
||||
EchoCppSideConnection() :
|
||||
message_count_(0),
|
||||
termination_seen_(false) {
|
||||
}
|
||||
~EchoCppSideConnection() override {}
|
||||
|
||||
// js_to_cpp::CppSide:
|
||||
void StartTest() override {
|
||||
js_side_->Echo(kExpectedMessageCount, BuildSampleEchoArgs());
|
||||
}
|
||||
|
||||
void EchoResponse(js_to_cpp::EchoArgsListPtr list) override {
|
||||
const js_to_cpp::EchoArgsPtr& special_arg = list->item;
|
||||
message_count_ += 1;
|
||||
EXPECT_EQ(-1, special_arg->si64);
|
||||
EXPECT_EQ(-1, special_arg->si32);
|
||||
EXPECT_EQ(-1, special_arg->si16);
|
||||
EXPECT_EQ(-1, special_arg->si8);
|
||||
EXPECT_EQ(std::string("going"), special_arg->name.To<std::string>());
|
||||
CheckSampleEchoArgsList(list->next);
|
||||
}
|
||||
|
||||
void TestFinished() override {
|
||||
termination_seen_ = true;
|
||||
run_loop()->Quit();
|
||||
}
|
||||
|
||||
bool DidSucceed() {
|
||||
return termination_seen_ &&
|
||||
!mishandled_messages_ &&
|
||||
message_count_ == kExpectedMessageCount;
|
||||
}
|
||||
|
||||
private:
|
||||
static const int kExpectedMessageCount = 10;
|
||||
int message_count_;
|
||||
bool termination_seen_;
|
||||
DISALLOW_COPY_AND_ASSIGN(EchoCppSideConnection);
|
||||
};
|
||||
|
||||
// Test that corrupted messages don't wreak havoc.
|
||||
class BitFlipCppSideConnection : public CppSideConnection {
|
||||
public:
|
||||
BitFlipCppSideConnection() : termination_seen_(false) {}
|
||||
~BitFlipCppSideConnection() override {}
|
||||
|
||||
// js_to_cpp::CppSide:
|
||||
void StartTest() override { js_side_->BitFlip(BuildSampleEchoArgs()); }
|
||||
|
||||
void BitFlipResponse(js_to_cpp::EchoArgsListPtr list) override {
|
||||
CheckCorruptedEchoArgsList(list);
|
||||
}
|
||||
|
||||
void TestFinished() override {
|
||||
termination_seen_ = true;
|
||||
run_loop()->Quit();
|
||||
}
|
||||
|
||||
bool DidSucceed() {
|
||||
return termination_seen_;
|
||||
}
|
||||
|
||||
private:
|
||||
bool termination_seen_;
|
||||
DISALLOW_COPY_AND_ASSIGN(BitFlipCppSideConnection);
|
||||
};
|
||||
|
||||
// Test that severely random messages don't wreak havoc.
|
||||
class BackPointerCppSideConnection : public CppSideConnection {
|
||||
public:
|
||||
BackPointerCppSideConnection() : termination_seen_(false) {}
|
||||
~BackPointerCppSideConnection() override {}
|
||||
|
||||
// js_to_cpp::CppSide:
|
||||
void StartTest() override { js_side_->BackPointer(BuildSampleEchoArgs()); }
|
||||
|
||||
void BackPointerResponse(js_to_cpp::EchoArgsListPtr list) override {
|
||||
CheckCorruptedEchoArgsList(list);
|
||||
}
|
||||
|
||||
void TestFinished() override {
|
||||
termination_seen_ = true;
|
||||
run_loop()->Quit();
|
||||
}
|
||||
|
||||
bool DidSucceed() {
|
||||
return termination_seen_;
|
||||
}
|
||||
|
||||
private:
|
||||
bool termination_seen_;
|
||||
DISALLOW_COPY_AND_ASSIGN(BackPointerCppSideConnection);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
class JsToCppTest : public testing::Test {
|
||||
public:
|
||||
JsToCppTest() {}
|
||||
|
||||
void RunTest(const std::string& test, CppSideConnection* cpp_side) {
|
||||
cpp_side->set_run_loop(&run_loop_);
|
||||
|
||||
MessagePipe pipe;
|
||||
js_to_cpp::JsSidePtr js_side =
|
||||
MakeProxy<js_to_cpp::JsSide>(pipe.handle0.Pass());
|
||||
js_side.set_client(cpp_side);
|
||||
|
||||
js_side.internal_state()->router_for_testing()->EnableTestingMode();
|
||||
|
||||
cpp_side->set_js_side(js_side.get());
|
||||
|
||||
gin::IsolateHolder::Initialize(gin::IsolateHolder::kStrictMode,
|
||||
gin::ArrayBufferAllocator::SharedInstance());
|
||||
gin::IsolateHolder instance;
|
||||
MojoRunnerDelegate delegate;
|
||||
gin::ShellRunner runner(&delegate, instance.isolate());
|
||||
delegate.Start(&runner, pipe.handle1.release().value(), test);
|
||||
|
||||
run_loop_.Run();
|
||||
}
|
||||
|
||||
private:
|
||||
base::ShadowingAtExitManager at_exit_;
|
||||
base::MessageLoop loop;
|
||||
base::RunLoop run_loop_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(JsToCppTest);
|
||||
};
|
||||
|
||||
TEST_F(JsToCppTest, Ping) {
|
||||
PingCppSideConnection cpp_side_connection;
|
||||
RunTest("mojo/edk/js/tests/js_to_cpp_tests", &cpp_side_connection);
|
||||
EXPECT_TRUE(cpp_side_connection.DidSucceed());
|
||||
}
|
||||
|
||||
TEST_F(JsToCppTest, Echo) {
|
||||
EchoCppSideConnection cpp_side_connection;
|
||||
RunTest("mojo/edk/js/tests/js_to_cpp_tests", &cpp_side_connection);
|
||||
EXPECT_TRUE(cpp_side_connection.DidSucceed());
|
||||
}
|
||||
|
||||
TEST_F(JsToCppTest, BitFlip) {
|
||||
BitFlipCppSideConnection cpp_side_connection;
|
||||
RunTest("mojo/edk/js/tests/js_to_cpp_tests", &cpp_side_connection);
|
||||
EXPECT_TRUE(cpp_side_connection.DidSucceed());
|
||||
}
|
||||
|
||||
TEST_F(JsToCppTest, BackPointer) {
|
||||
BackPointerCppSideConnection cpp_side_connection;
|
||||
RunTest("mojo/edk/js/tests/js_to_cpp_tests", &cpp_side_connection);
|
||||
EXPECT_TRUE(cpp_side_connection.DidSucceed());
|
||||
}
|
||||
|
||||
} // namespace js
|
||||
} // namespace mojo
|
221
mojo/edk/js/tests/js_to_cpp_tests.js
Normal file
221
mojo/edk/js/tests/js_to_cpp_tests.js
Normal file
@ -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.
|
||||
|
||||
define('mojo/edk/js/tests/js_to_cpp_tests', [
|
||||
'console',
|
||||
'mojo/edk/js/tests/js_to_cpp.mojom',
|
||||
'mojo/public/js/connection',
|
||||
'mojo/public/js/connector',
|
||||
'mojo/public/js/core',
|
||||
], function (console, jsToCpp, connection, connector, core) {
|
||||
var retainedConnection;
|
||||
var sampleData;
|
||||
var sampleMessage;
|
||||
var BAD_VALUE = 13;
|
||||
var DATA_PIPE_PARAMS = {
|
||||
flags: core.CREATE_DATA_PIPE_OPTIONS_FLAG_NONE,
|
||||
elementNumBytes: 1,
|
||||
capacityNumBytes: 64
|
||||
};
|
||||
|
||||
function JsSideConnection(cppSide) {
|
||||
this.cppSide_ = cppSide;
|
||||
cppSide.startTest();
|
||||
}
|
||||
|
||||
JsSideConnection.prototype =
|
||||
Object.create(jsToCpp.JsSide.stubClass.prototype);
|
||||
|
||||
JsSideConnection.prototype.ping = function (arg) {
|
||||
this.cppSide_.pingResponse();
|
||||
};
|
||||
|
||||
JsSideConnection.prototype.echo = function (numIterations, arg) {
|
||||
var dataPipe1;
|
||||
var dataPipe2;
|
||||
var i;
|
||||
var messagePipe1;
|
||||
var messagePipe2;
|
||||
var specialArg;
|
||||
|
||||
// Ensure expected negative values are negative.
|
||||
if (arg.si64 > 0)
|
||||
arg.si64 = BAD_VALUE;
|
||||
|
||||
if (arg.si32 > 0)
|
||||
arg.si32 = BAD_VALUE;
|
||||
|
||||
if (arg.si16 > 0)
|
||||
arg.si16 = BAD_VALUE;
|
||||
|
||||
if (arg.si8 > 0)
|
||||
arg.si8 = BAD_VALUE;
|
||||
|
||||
for (i = 0; i < numIterations; ++i) {
|
||||
dataPipe1 = core.createDataPipe(DATA_PIPE_PARAMS);
|
||||
dataPipe2 = core.createDataPipe(DATA_PIPE_PARAMS);
|
||||
messagePipe1 = core.createMessagePipe();
|
||||
messagePipe2 = core.createMessagePipe();
|
||||
|
||||
arg.data_handle = dataPipe1.consumerHandle;
|
||||
arg.message_handle = messagePipe1.handle1;
|
||||
|
||||
specialArg = new jsToCpp.EchoArgs();
|
||||
specialArg.si64 = -1;
|
||||
specialArg.si32 = -1;
|
||||
specialArg.si16 = -1;
|
||||
specialArg.si8 = -1;
|
||||
specialArg.name = 'going';
|
||||
specialArg.data_handle = dataPipe2.consumerHandle;
|
||||
specialArg.message_handle = messagePipe2.handle1;
|
||||
|
||||
writeDataPipe(dataPipe1, sampleData);
|
||||
writeDataPipe(dataPipe2, sampleData);
|
||||
writeMessagePipe(messagePipe1, sampleMessage);
|
||||
writeMessagePipe(messagePipe2, sampleMessage);
|
||||
|
||||
this.cppSide_.echoResponse(createEchoArgsList(specialArg, arg));
|
||||
|
||||
core.close(dataPipe1.producerHandle);
|
||||
core.close(dataPipe2.producerHandle);
|
||||
core.close(messagePipe1.handle0);
|
||||
core.close(messagePipe2.handle0);
|
||||
}
|
||||
this.cppSide_.testFinished();
|
||||
};
|
||||
|
||||
JsSideConnection.prototype.bitFlip = function (arg) {
|
||||
var iteration = 0;
|
||||
var dataPipe;
|
||||
var messagePipe;
|
||||
var proto = connector.Connector.prototype;
|
||||
var stopSignalled = false;
|
||||
|
||||
proto.realAccept = proto.accept;
|
||||
proto.accept = function (message) {
|
||||
var offset = iteration / 8;
|
||||
var mask;
|
||||
var value;
|
||||
if (offset < message.buffer.arrayBuffer.byteLength) {
|
||||
mask = 1 << (iteration % 8);
|
||||
value = message.buffer.getUint8(offset) ^ mask;
|
||||
message.buffer.setUint8(offset, value);
|
||||
return this.realAccept(message);
|
||||
}
|
||||
stopSignalled = true;
|
||||
return false;
|
||||
};
|
||||
|
||||
while (!stopSignalled) {
|
||||
dataPipe = core.createDataPipe(DATA_PIPE_PARAMS);
|
||||
messagePipe = core.createMessagePipe();
|
||||
writeDataPipe(dataPipe, sampleData);
|
||||
writeMessagePipe(messagePipe, sampleMessage);
|
||||
arg.data_handle = dataPipe.consumerHandle;
|
||||
arg.message_handle = messagePipe.handle1;
|
||||
|
||||
this.cppSide_.bitFlipResponse(createEchoArgsList(arg));
|
||||
|
||||
core.close(dataPipe.producerHandle);
|
||||
core.close(messagePipe.handle0);
|
||||
iteration += 1;
|
||||
}
|
||||
|
||||
proto.accept = proto.realAccept;
|
||||
proto.realAccept = null;
|
||||
this.cppSide_.testFinished();
|
||||
};
|
||||
|
||||
JsSideConnection.prototype.backPointer = function (arg) {
|
||||
var iteration = 0;
|
||||
var dataPipe;
|
||||
var messagePipe;
|
||||
var proto = connector.Connector.prototype;
|
||||
var stopSignalled = false;
|
||||
|
||||
proto.realAccept = proto.accept;
|
||||
proto.accept = function (message) {
|
||||
var delta = 8 * (1 + iteration % 32);
|
||||
var offset = 8 * ((iteration / 32) | 0);
|
||||
if (offset < message.buffer.arrayBuffer.byteLength - 4) {
|
||||
message.buffer.dataView.setUint32(offset, 0x100000000 - delta, true);
|
||||
message.buffer.dataView.setUint32(offset + 4, 0xffffffff, true);
|
||||
return this.realAccept(message);
|
||||
}
|
||||
stopSignalled = true;
|
||||
return false;
|
||||
};
|
||||
|
||||
while (!stopSignalled) {
|
||||
dataPipe = core.createDataPipe(DATA_PIPE_PARAMS);
|
||||
messagePipe = core.createMessagePipe();
|
||||
writeDataPipe(dataPipe, sampleData);
|
||||
writeMessagePipe(messagePipe, sampleMessage);
|
||||
arg.data_handle = dataPipe.consumerHandle;
|
||||
arg.message_handle = messagePipe.handle1;
|
||||
|
||||
this.cppSide_.backPointerResponse(createEchoArgsList(arg));
|
||||
|
||||
core.close(dataPipe.producerHandle);
|
||||
core.close(messagePipe.handle0);
|
||||
iteration += 1;
|
||||
}
|
||||
|
||||
proto.accept = proto.realAccept;
|
||||
proto.realAccept = null;
|
||||
this.cppSide_.testFinished();
|
||||
};
|
||||
|
||||
function writeDataPipe(pipe, data) {
|
||||
var writeResult = core.writeData(
|
||||
pipe.producerHandle, data, core.WRITE_DATA_FLAG_ALL_OR_NONE);
|
||||
|
||||
if (writeResult.result != core.RESULT_OK) {
|
||||
console.log('ERROR: Data pipe write result was ' + writeResult.result);
|
||||
return false;
|
||||
}
|
||||
if (writeResult.numBytes != data.length) {
|
||||
console.log('ERROR: Data pipe write length was ' + writeResult.numBytes);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function writeMessagePipe(pipe, arrayBuffer) {
|
||||
var result = core.writeMessage(pipe.handle0, arrayBuffer, [], 0);
|
||||
if (result != core.RESULT_OK) {
|
||||
console.log('ERROR: Message pipe write result was ' + result);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function createEchoArgsListElement(item, next) {
|
||||
var list = new jsToCpp.EchoArgsList();
|
||||
list.item = item;
|
||||
list.next = next;
|
||||
return list;
|
||||
}
|
||||
|
||||
function createEchoArgsList() {
|
||||
var genuineArray = Array.prototype.slice.call(arguments);
|
||||
return genuineArray.reduceRight(function (previous, current) {
|
||||
return createEchoArgsListElement(current, previous);
|
||||
}, null);
|
||||
}
|
||||
|
||||
return function(handle) {
|
||||
var i;
|
||||
sampleData = new Uint8Array(DATA_PIPE_PARAMS.capacityNumBytes);
|
||||
for (i = 0; i < sampleData.length; ++i) {
|
||||
sampleData[i] = i;
|
||||
}
|
||||
sampleMessage = new Uint8Array(DATA_PIPE_PARAMS.capacityNumBytes);
|
||||
for (i = 0; i < sampleMessage.length; ++i) {
|
||||
sampleMessage[i] = 255 - i;
|
||||
}
|
||||
retainedConnection = new connection.Connection(handle, JsSideConnection,
|
||||
jsToCpp.CppSide.proxyClass);
|
||||
};
|
||||
});
|
168
mojo/edk/js/tests/sample_service_tests.js
Normal file
168
mojo/edk/js/tests/sample_service_tests.js
Normal file
@ -0,0 +1,168 @@
|
||||
// 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.
|
||||
|
||||
define([
|
||||
"console",
|
||||
"mojo/edk/js/test/hexdump",
|
||||
"gin/test/expect",
|
||||
"mojo/public/interfaces/bindings/tests/sample_service.mojom",
|
||||
"mojo/public/interfaces/bindings/tests/sample_import.mojom",
|
||||
"mojo/public/interfaces/bindings/tests/sample_import2.mojom",
|
||||
], function(console, hexdump, expect, sample, imported, imported2) {
|
||||
|
||||
var global = this;
|
||||
|
||||
// Set this variable to true to print the binary message in hex.
|
||||
var dumpMessageAsHex = false;
|
||||
|
||||
function makeFoo() {
|
||||
var bar = new sample.Bar();
|
||||
bar.alpha = 20;
|
||||
bar.beta = 40;
|
||||
bar.gamma = 60;
|
||||
bar.type = sample.Bar.Type.VERTICAL;
|
||||
|
||||
var extra_bars = new Array(3);
|
||||
for (var i = 0; i < extra_bars.length; ++i) {
|
||||
var base = i * 100;
|
||||
var type = i % 2 ?
|
||||
sample.Bar.Type.VERTICAL : sample.Bar.Type.HORIZONTAL;
|
||||
extra_bars[i] = new sample.Bar();
|
||||
extra_bars[i].alpha = base;
|
||||
extra_bars[i].beta = base + 20;
|
||||
extra_bars[i].gamma = base + 40;
|
||||
extra_bars[i].type = type;
|
||||
}
|
||||
|
||||
var data = new Array(10);
|
||||
for (var i = 0; i < data.length; ++i) {
|
||||
data[i] = data.length - i;
|
||||
}
|
||||
|
||||
var source = 0xFFFF; // Invent a dummy handle.
|
||||
|
||||
var foo = new sample.Foo();
|
||||
foo.name = "foopy";
|
||||
foo.x = 1;
|
||||
foo.y = 2;
|
||||
foo.a = false;
|
||||
foo.b = true;
|
||||
foo.c = false;
|
||||
foo.bar = bar;
|
||||
foo.extra_bars = extra_bars;
|
||||
foo.data = data;
|
||||
foo.source = source;
|
||||
return foo;
|
||||
}
|
||||
|
||||
// Check that the given |Foo| is identical to the one made by |MakeFoo()|.
|
||||
function checkFoo(foo) {
|
||||
expect(foo.name).toBe("foopy");
|
||||
expect(foo.x).toBe(1);
|
||||
expect(foo.y).toBe(2);
|
||||
expect(foo.a).toBeFalsy();
|
||||
expect(foo.b).toBeTruthy();
|
||||
expect(foo.c).toBeFalsy();
|
||||
expect(foo.bar.alpha).toBe(20);
|
||||
expect(foo.bar.beta).toBe(40);
|
||||
expect(foo.bar.gamma).toBe(60);
|
||||
expect(foo.bar.type).toBe(sample.Bar.Type.VERTICAL);
|
||||
|
||||
expect(foo.extra_bars.length).toBe(3);
|
||||
for (var i = 0; i < foo.extra_bars.length; ++i) {
|
||||
var base = i * 100;
|
||||
var type = i % 2 ?
|
||||
sample.Bar.Type.VERTICAL : sample.Bar.Type.HORIZONTAL;
|
||||
expect(foo.extra_bars[i].alpha).toBe(base);
|
||||
expect(foo.extra_bars[i].beta).toBe(base + 20);
|
||||
expect(foo.extra_bars[i].gamma).toBe(base + 40);
|
||||
expect(foo.extra_bars[i].type).toBe(type);
|
||||
}
|
||||
|
||||
expect(foo.data.length).toBe(10);
|
||||
for (var i = 0; i < foo.data.length; ++i)
|
||||
expect(foo.data[i]).toBe(foo.data.length - i);
|
||||
|
||||
expect(foo.source).toBe(0xFFFF);
|
||||
}
|
||||
|
||||
// Check that values are set to the defaults if we don't override them.
|
||||
function checkDefaultValues() {
|
||||
var bar = new sample.Bar();
|
||||
expect(bar.alpha).toBe(255);
|
||||
expect(bar.type).toBe(sample.Bar.Type.VERTICAL);
|
||||
|
||||
var foo = new sample.Foo();
|
||||
expect(foo.name).toBe("Fooby");
|
||||
expect(foo.a).toBeTruthy();
|
||||
expect(foo.data).toBeNull();
|
||||
|
||||
var defaults = new sample.DefaultsTest();
|
||||
expect(defaults.a0).toBe(-12);
|
||||
expect(defaults.a1).toBe(sample.kTwelve);
|
||||
expect(defaults.a2).toBe(1234);
|
||||
expect(defaults.a3).toBe(34567);
|
||||
expect(defaults.a4).toBe(123456);
|
||||
expect(defaults.a5).toBe(3456789012);
|
||||
expect(defaults.a6).toBe(-111111111111);
|
||||
// JS doesn't have a 64 bit integer type so this is just checking that the
|
||||
// expected and actual values have the same closest double value.
|
||||
expect(defaults.a7).toBe(9999999999999999999);
|
||||
expect(defaults.a8).toBe(0x12345);
|
||||
expect(defaults.a9).toBe(-0x12345);
|
||||
expect(defaults.a10).toBe(1234);
|
||||
expect(defaults.a11).toBe(true);
|
||||
expect(defaults.a12).toBe(false);
|
||||
expect(defaults.a13).toBe(123.25);
|
||||
expect(defaults.a14).toBe(1234567890.123);
|
||||
expect(defaults.a15).toBe(1E10);
|
||||
expect(defaults.a16).toBe(-1.2E+20);
|
||||
expect(defaults.a17).toBe(1.23E-20);
|
||||
expect(defaults.a20).toBe(sample.Bar.Type.BOTH);
|
||||
expect(defaults.a21).toBeNull();
|
||||
expect(defaults.a22).toBeTruthy();
|
||||
expect(defaults.a22.shape).toBe(imported.Shape.RECTANGLE);
|
||||
expect(defaults.a22.color).toBe(imported2.Color.BLACK);
|
||||
expect(defaults.a21).toBeNull();
|
||||
expect(defaults.a23).toBe(0xFFFFFFFFFFFFFFFF);
|
||||
expect(defaults.a24).toBe(0x123456789);
|
||||
expect(defaults.a25).toBe(-0x123456789);
|
||||
}
|
||||
|
||||
function ServiceImpl() {
|
||||
}
|
||||
|
||||
ServiceImpl.prototype = Object.create(sample.Service.stubClass.prototype);
|
||||
|
||||
ServiceImpl.prototype.frobinate = function(foo, baz, port) {
|
||||
checkFoo(foo);
|
||||
expect(baz).toBe(sample.Service.BazOptions.EXTRA);
|
||||
expect(port).toBe(10);
|
||||
global.result = "PASS";
|
||||
};
|
||||
|
||||
function SimpleMessageReceiver() {
|
||||
}
|
||||
|
||||
SimpleMessageReceiver.prototype.accept = function(message) {
|
||||
if (dumpMessageAsHex) {
|
||||
var uint8Array = new Uint8Array(message.buffer.arrayBuffer);
|
||||
console.log(hexdump.dumpArray(uint8Array));
|
||||
}
|
||||
// Imagine some IPC happened here.
|
||||
var serviceImpl = new ServiceImpl();
|
||||
serviceImpl.accept(message);
|
||||
};
|
||||
|
||||
var receiver = new SimpleMessageReceiver();
|
||||
var serviceProxy = new sample.Service.proxyClass(receiver);
|
||||
|
||||
checkDefaultValues();
|
||||
|
||||
var foo = makeFoo();
|
||||
checkFoo(foo);
|
||||
|
||||
var port = 10;
|
||||
serviceProxy.frobinate(foo, sample.Service.BazOptions.EXTRA, port);
|
||||
});
|
47
mojo/edk/js/threading.cc
Normal file
47
mojo/edk/js/threading.cc
Normal file
@ -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.
|
||||
|
||||
#include "mojo/edk/js/threading.h"
|
||||
|
||||
#include "base/message_loop/message_loop.h"
|
||||
#include "gin/object_template_builder.h"
|
||||
#include "gin/per_isolate_data.h"
|
||||
#include "mojo/edk/js/handle.h"
|
||||
|
||||
namespace mojo {
|
||||
namespace js {
|
||||
|
||||
namespace {
|
||||
|
||||
void Quit() {
|
||||
base::MessageLoop::current()->QuitNow();
|
||||
}
|
||||
|
||||
gin::WrapperInfo g_wrapper_info = { gin::kEmbedderNativeGin };
|
||||
|
||||
} // namespace
|
||||
|
||||
const char Threading::kModuleName[] = "mojo/public/js/threading";
|
||||
|
||||
v8::Local<v8::Value> Threading::GetModule(v8::Isolate* isolate) {
|
||||
gin::PerIsolateData* data = gin::PerIsolateData::From(isolate);
|
||||
v8::Local<v8::ObjectTemplate> templ = data->GetObjectTemplate(
|
||||
&g_wrapper_info);
|
||||
|
||||
if (templ.IsEmpty()) {
|
||||
templ = gin::ObjectTemplateBuilder(isolate)
|
||||
.SetMethod("quit", Quit)
|
||||
.Build();
|
||||
|
||||
data->SetObjectTemplate(&g_wrapper_info, templ);
|
||||
}
|
||||
|
||||
return templ->NewInstance();
|
||||
}
|
||||
|
||||
Threading::Threading() {
|
||||
}
|
||||
|
||||
} // namespace js
|
||||
} // namespace mojo
|
25
mojo/edk/js/threading.h
Normal file
25
mojo/edk/js/threading.h
Normal file
@ -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_EDK_JS_THREADING_H_
|
||||
#define MOJO_EDK_JS_THREADING_H_
|
||||
|
||||
#include "gin/public/wrapper_info.h"
|
||||
#include "v8/include/v8.h"
|
||||
|
||||
namespace mojo {
|
||||
namespace js {
|
||||
|
||||
class Threading {
|
||||
public:
|
||||
static const char kModuleName[];
|
||||
static v8::Local<v8::Value> GetModule(v8::Isolate* isolate);
|
||||
private:
|
||||
Threading();
|
||||
};
|
||||
|
||||
} // namespace js
|
||||
} // namespace mojo
|
||||
|
||||
#endif // MOJO_EDK_JS_THREADING_H_
|
@ -2,8 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef MOJO_BINDINGS_JS_WAITING_CALLBACK_H_
|
||||
#define MOJO_BINDINGS_JS_WAITING_CALLBACK_H_
|
||||
#ifndef MOJO_EDK_JS_WAITING_CALLBACK_H_
|
||||
#define MOJO_EDK_JS_WAITING_CALLBACK_H_
|
||||
|
||||
#include "gin/handle.h"
|
||||
#include "gin/runner.h"
|
||||
@ -60,4 +60,4 @@ class WaitingCallback : public gin::Wrappable<WaitingCallback>,
|
||||
} // namespace js
|
||||
} // namespace mojo
|
||||
|
||||
#endif // MOJO_BINDINGS_JS_WAITING_CALLBACK_H_
|
||||
#endif // MOJO_EDK_JS_WAITING_CALLBACK_H_
|
||||
|
@ -2,195 +2,11 @@
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
# Essential components (and their tests) that are needed to build
|
||||
# Chrome should be here. Other components that are useful only in
|
||||
# Mojo land like mojo_shell should be in mojo.gyp.
|
||||
{
|
||||
'includes': [
|
||||
'../mojo_variables.gypi',
|
||||
],
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'mojo_edk',
|
||||
'type': 'none',
|
||||
'dependencies': [
|
||||
# NOTE: If adding a new dependency here, please consider whether it
|
||||
# should also be added to the list of Mojo-related dependencies of
|
||||
# build/all.gyp:All on iOS, as All cannot depend on the mojo_base
|
||||
# target on iOS due to the presence of the js targets, which cause v8
|
||||
# to be built.
|
||||
'mojo_message_pipe_perftests',
|
||||
'mojo_public_application_unittests',
|
||||
'mojo_public_bindings_unittests',
|
||||
'mojo_public_environment_unittests',
|
||||
'mojo_public_system_perftests',
|
||||
'mojo_public_system_unittests',
|
||||
'mojo_public_utility_unittests',
|
||||
'mojo_system_impl',
|
||||
'mojo_system_unittests',
|
||||
'mojo_js_unittests',
|
||||
],
|
||||
},
|
||||
{
|
||||
'target_name': 'mojo_none',
|
||||
'type': 'none',
|
||||
},
|
||||
{
|
||||
# GN version: //mojo/edk/test:run_all_unittests
|
||||
'target_name': 'mojo_run_all_unittests',
|
||||
'type': 'static_library',
|
||||
'dependencies': [
|
||||
'../../base/base.gyp:base',
|
||||
'../../base/base.gyp:test_support_base',
|
||||
'../../testing/gtest.gyp:gtest',
|
||||
'mojo_system_impl',
|
||||
'mojo_test_support_impl',
|
||||
'../public/mojo_public.gyp:mojo_test_support',
|
||||
],
|
||||
'sources': [
|
||||
'test/run_all_unittests.cc',
|
||||
],
|
||||
},
|
||||
{
|
||||
# GN version: //mojo/edk/test:run_all_perftests
|
||||
'target_name': 'mojo_run_all_perftests',
|
||||
'type': 'static_library',
|
||||
'dependencies': [
|
||||
'../../base/base.gyp:test_support_base',
|
||||
'mojo_system_impl',
|
||||
'mojo_test_support_impl',
|
||||
'../public/mojo_public.gyp:mojo_test_support',
|
||||
],
|
||||
'sources': [
|
||||
'test/run_all_perftests.cc',
|
||||
],
|
||||
},
|
||||
# TODO(vtl): Reorganize the mojo_public_*_unittests.
|
||||
{
|
||||
# GN version: //mojo/public/cpp/bindings/tests:mojo_public_bindings_unittests
|
||||
'target_name': 'mojo_public_bindings_unittests',
|
||||
'type': 'executable',
|
||||
'dependencies': [
|
||||
'../../testing/gtest.gyp:gtest',
|
||||
'mojo_run_all_unittests',
|
||||
'../public/mojo_public.gyp:mojo_cpp_bindings',
|
||||
'../public/mojo_public.gyp:mojo_environment_standalone',
|
||||
'../public/mojo_public.gyp:mojo_public_bindings_test_utils',
|
||||
'../public/mojo_public.gyp:mojo_public_test_interfaces',
|
||||
'../public/mojo_public.gyp:mojo_public_test_utils',
|
||||
'../public/mojo_public.gyp:mojo_utility',
|
||||
],
|
||||
'sources': [
|
||||
'../public/cpp/bindings/tests/array_unittest.cc',
|
||||
'../public/cpp/bindings/tests/bounds_checker_unittest.cc',
|
||||
'../public/cpp/bindings/tests/buffer_unittest.cc',
|
||||
'../public/cpp/bindings/tests/connector_unittest.cc',
|
||||
'../public/cpp/bindings/tests/container_test_util.cc',
|
||||
'../public/cpp/bindings/tests/equals_unittest.cc',
|
||||
'../public/cpp/bindings/tests/handle_passing_unittest.cc',
|
||||
'../public/cpp/bindings/tests/interface_ptr_unittest.cc',
|
||||
'../public/cpp/bindings/tests/map_unittest.cc',
|
||||
'../public/cpp/bindings/tests/request_response_unittest.cc',
|
||||
'../public/cpp/bindings/tests/router_unittest.cc',
|
||||
'../public/cpp/bindings/tests/sample_service_unittest.cc',
|
||||
'../public/cpp/bindings/tests/serialization_warning_unittest.cc',
|
||||
'../public/cpp/bindings/tests/string_unittest.cc',
|
||||
'../public/cpp/bindings/tests/struct_unittest.cc',
|
||||
'../public/cpp/bindings/tests/type_conversion_unittest.cc',
|
||||
'../public/cpp/bindings/tests/validation_unittest.cc',
|
||||
],
|
||||
},
|
||||
{
|
||||
# GN version: //mojo/public/cpp/environment/tests:mojo_public_environment_unittests
|
||||
'target_name': 'mojo_public_environment_unittests',
|
||||
'type': 'executable',
|
||||
'dependencies': [
|
||||
'../../testing/gtest.gyp:gtest',
|
||||
'mojo_run_all_unittests',
|
||||
'../public/mojo_public.gyp:mojo_environment_standalone',
|
||||
'../public/mojo_public.gyp:mojo_public_test_utils',
|
||||
'../public/mojo_public.gyp:mojo_utility',
|
||||
],
|
||||
'include_dirs': [ '../..' ],
|
||||
'sources': [
|
||||
'../public/cpp/environment/tests/async_wait_unittest.cc',
|
||||
'../public/cpp/environment/tests/async_waiter_unittest.cc',
|
||||
'../public/cpp/environment/tests/logger_unittest.cc',
|
||||
'../public/cpp/environment/tests/logging_unittest.cc',
|
||||
],
|
||||
},
|
||||
{
|
||||
# GN version: //mojo/public/cpp/application/tests:mojo_public_application_unittests
|
||||
'target_name': 'mojo_public_application_unittests',
|
||||
'type': 'executable',
|
||||
'dependencies': [
|
||||
'../../base/base.gyp:base',
|
||||
'../../testing/gtest.gyp:gtest',
|
||||
'mojo_run_all_unittests',
|
||||
'../public/mojo_public.gyp:mojo_application_standalone',
|
||||
'../public/mojo_public.gyp:mojo_utility',
|
||||
'../public/mojo_public.gyp:mojo_environment_standalone',
|
||||
],
|
||||
'sources': [
|
||||
'../public/cpp/application/tests/service_registry_unittest.cc',
|
||||
],
|
||||
},
|
||||
{
|
||||
# GN version: //mojo/public/cpp/application/tests:mojo_public_system_unittests
|
||||
'target_name': 'mojo_public_system_unittests',
|
||||
'type': 'executable',
|
||||
'dependencies': [
|
||||
'../../testing/gtest.gyp:gtest',
|
||||
'mojo_run_all_unittests',
|
||||
'../public/mojo_public.gyp:mojo_public_test_utils',
|
||||
],
|
||||
'include_dirs': [ '../..' ],
|
||||
'sources': [
|
||||
'<@(mojo_public_system_unittest_sources)',
|
||||
],
|
||||
},
|
||||
{
|
||||
# GN version: //mojo/public/cpp/application/tests:mojo_public_utility_unittests
|
||||
'target_name': 'mojo_public_utility_unittests',
|
||||
'type': 'executable',
|
||||
'dependencies': [
|
||||
'../../testing/gtest.gyp:gtest',
|
||||
'mojo_run_all_unittests',
|
||||
'../public/mojo_public.gyp:mojo_public_test_utils',
|
||||
'../public/mojo_public.gyp:mojo_utility',
|
||||
],
|
||||
'include_dirs': [ '../..' ],
|
||||
'sources': [
|
||||
'../public/cpp/utility/tests/mutex_unittest.cc',
|
||||
'../public/cpp/utility/tests/run_loop_unittest.cc',
|
||||
'../public/cpp/utility/tests/thread_unittest.cc',
|
||||
],
|
||||
'conditions': [
|
||||
# See crbug.com/342893:
|
||||
['OS=="win"', {
|
||||
'sources!': [
|
||||
'../public/cpp/utility/tests/mutex_unittest.cc',
|
||||
'../public/cpp/utility/tests/thread_unittest.cc',
|
||||
],
|
||||
}],
|
||||
],
|
||||
},
|
||||
{
|
||||
# GN version: //mojo/public/c/system/tests:perftests
|
||||
'target_name': 'mojo_public_system_perftests',
|
||||
'type': 'executable',
|
||||
'dependencies': [
|
||||
'../../base/base.gyp:base',
|
||||
'../../testing/gtest.gyp:gtest',
|
||||
'mojo_run_all_perftests',
|
||||
'../public/mojo_public.gyp:mojo_public_test_utils',
|
||||
'../public/mojo_public.gyp:mojo_utility',
|
||||
],
|
||||
'sources': [
|
||||
'../public/c/system/tests/core_perftest.cc',
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
# GN version: //mojo/edk/system
|
||||
'target_name': 'mojo_system_impl',
|
||||
@ -205,11 +21,14 @@
|
||||
'MOJO_USE_SYSTEM_IMPL',
|
||||
],
|
||||
'sources': [
|
||||
'embedder/configuration.h',
|
||||
'embedder/channel_info_forward.h',
|
||||
'embedder/channel_init.cc',
|
||||
'embedder/channel_init.h',
|
||||
'embedder/embedder.cc',
|
||||
'embedder/embedder.h',
|
||||
'embedder/embedder_internal.h',
|
||||
'embedder/entrypoints.cc',
|
||||
'embedder/platform_channel_pair.cc',
|
||||
'embedder/platform_channel_pair.h',
|
||||
'embedder/platform_channel_pair_posix.cc',
|
||||
@ -239,7 +58,10 @@
|
||||
'system/channel_endpoint_id.h',
|
||||
'system/channel_info.cc',
|
||||
'system/channel_info.h',
|
||||
'system/constants.h',
|
||||
'system/channel_manager.cc',
|
||||
'system/channel_manager.h',
|
||||
'system/configuration.cc',
|
||||
'system/configuration.h',
|
||||
'system/core.cc',
|
||||
'system/core.h',
|
||||
'system/data_pipe.cc',
|
||||
@ -250,7 +72,6 @@
|
||||
'system/data_pipe_producer_dispatcher.h',
|
||||
'system/dispatcher.cc',
|
||||
'system/dispatcher.h',
|
||||
'system/entrypoints.cc',
|
||||
'system/handle_signals_state.h',
|
||||
'system/handle_table.cc',
|
||||
'system/handle_table.h',
|
||||
@ -303,77 +124,6 @@
|
||||
'defines': ['MOJO_USE_SYSTEM_IMPL'],
|
||||
}
|
||||
},
|
||||
{
|
||||
# GN version: //mojo/edk/system:mojo_system_unittests
|
||||
'target_name': 'mojo_system_unittests',
|
||||
'type': 'executable',
|
||||
'dependencies': [
|
||||
'../../base/base.gyp:base',
|
||||
'../../testing/gtest.gyp:gtest',
|
||||
'mojo_common_test_support',
|
||||
'mojo_system_impl',
|
||||
],
|
||||
'sources': [
|
||||
'embedder/embedder_unittest.cc',
|
||||
'embedder/platform_channel_pair_posix_unittest.cc',
|
||||
'embedder/simple_platform_shared_buffer_unittest.cc',
|
||||
'system/channel_endpoint_id_unittest.cc',
|
||||
'system/channel_unittest.cc',
|
||||
'system/core_unittest.cc',
|
||||
'system/core_test_base.cc',
|
||||
'system/core_test_base.h',
|
||||
'system/data_pipe_unittest.cc',
|
||||
'system/dispatcher_unittest.cc',
|
||||
'system/local_data_pipe_unittest.cc',
|
||||
'system/memory_unittest.cc',
|
||||
'system/message_pipe_dispatcher_unittest.cc',
|
||||
'system/message_pipe_test_utils.h',
|
||||
'system/message_pipe_test_utils.cc',
|
||||
'system/message_pipe_unittest.cc',
|
||||
'system/multiprocess_message_pipe_unittest.cc',
|
||||
'system/options_validation_unittest.cc',
|
||||
'system/platform_handle_dispatcher_unittest.cc',
|
||||
'system/raw_channel_unittest.cc',
|
||||
'system/remote_message_pipe_unittest.cc',
|
||||
'system/run_all_unittests.cc',
|
||||
'system/shared_buffer_dispatcher_unittest.cc',
|
||||
'system/simple_dispatcher_unittest.cc',
|
||||
'system/test_utils.cc',
|
||||
'system/test_utils.h',
|
||||
'system/waiter_list_unittest.cc',
|
||||
'system/waiter_test_utils.cc',
|
||||
'system/waiter_test_utils.h',
|
||||
'system/waiter_unittest.cc',
|
||||
],
|
||||
'conditions': [
|
||||
['OS=="ios"', {
|
||||
'sources!': [
|
||||
'embedder/embedder_unittest.cc',
|
||||
'system/multiprocess_message_pipe_unittest.cc',
|
||||
],
|
||||
}],
|
||||
],
|
||||
},
|
||||
{
|
||||
# GN version: //mojo/edk/system:mojo_message_pipe_perftests
|
||||
'target_name': 'mojo_message_pipe_perftests',
|
||||
'type': 'executable',
|
||||
'dependencies': [
|
||||
'../../base/base.gyp:base',
|
||||
'../../base/base.gyp:test_support_base',
|
||||
'../../base/base.gyp:test_support_perf',
|
||||
'../../testing/gtest.gyp:gtest',
|
||||
'mojo_common_test_support',
|
||||
'mojo_system_impl',
|
||||
],
|
||||
'sources': [
|
||||
'system/message_pipe_perftest.cc',
|
||||
'system/message_pipe_test_utils.h',
|
||||
'system/message_pipe_test_utils.cc',
|
||||
'system/test_utils.cc',
|
||||
'system/test_utils.h',
|
||||
],
|
||||
},
|
||||
{
|
||||
# GN version: //mojo/edk/js
|
||||
'target_name': 'mojo_js_lib',
|
||||
@ -396,32 +146,18 @@
|
||||
'js/handle.cc',
|
||||
'js/handle.h',
|
||||
'js/handle_close_observer.h',
|
||||
'js/mojo_runner_delegate.cc',
|
||||
'js/mojo_runner_delegate.h',
|
||||
'js/support.cc',
|
||||
'js/support.h',
|
||||
'js/threading.cc',
|
||||
'js/threading.h',
|
||||
'js/waiting_callback.cc',
|
||||
'js/waiting_callback.h',
|
||||
],
|
||||
},
|
||||
{
|
||||
# GN version: //mojo/edk/js:js_unittests
|
||||
'target_name': 'mojo_js_unittests',
|
||||
'type': 'executable',
|
||||
'dependencies': [
|
||||
'../../gin/gin.gyp:gin_test',
|
||||
'mojo_common_test_support',
|
||||
'mojo_run_all_unittests',
|
||||
'mojo_js_lib',
|
||||
'../public/mojo_public.gyp:mojo_environment_standalone',
|
||||
'../public/mojo_public.gyp:mojo_public_test_interfaces',
|
||||
'../public/mojo_public.gyp:mojo_utility',
|
||||
],
|
||||
'sources': [
|
||||
'js/handle_unittest.cc',
|
||||
'js/tests/run_js_tests.cc',
|
||||
],
|
||||
},
|
||||
{
|
||||
# GN version: //mojo/common/test:test_support_impl
|
||||
# GN version: //mojo/edk/test:test_support_impl
|
||||
'target_name': 'mojo_test_support_impl',
|
||||
'type': 'static_library',
|
||||
'dependencies': [
|
||||
@ -457,5 +193,35 @@
|
||||
}],
|
||||
],
|
||||
},
|
||||
{
|
||||
# GN version: //mojo/edk/test:run_all_unittests
|
||||
'target_name': 'mojo_run_all_unittests',
|
||||
'type': 'static_library',
|
||||
'dependencies': [
|
||||
'../../base/base.gyp:base',
|
||||
'../../base/base.gyp:test_support_base',
|
||||
'../../testing/gtest.gyp:gtest',
|
||||
'mojo_system_impl',
|
||||
'mojo_test_support_impl',
|
||||
'../public/mojo_public.gyp:mojo_test_support',
|
||||
],
|
||||
'sources': [
|
||||
'test/run_all_unittests.cc',
|
||||
],
|
||||
},
|
||||
{
|
||||
# GN version: //mojo/edk/test:run_all_perftests
|
||||
'target_name': 'mojo_run_all_perftests',
|
||||
'type': 'static_library',
|
||||
'dependencies': [
|
||||
'../../base/base.gyp:test_support_base',
|
||||
'mojo_edk.gyp:mojo_system_impl',
|
||||
'mojo_test_support_impl',
|
||||
'../public/mojo_public.gyp:mojo_test_support',
|
||||
],
|
||||
'sources': [
|
||||
'test/run_all_perftests.cc',
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
278
mojo/edk/mojo_edk_tests.gyp
Normal file
278
mojo/edk/mojo_edk_tests.gyp
Normal file
@ -0,0 +1,278 @@
|
||||
# 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.
|
||||
|
||||
{
|
||||
'includes': [
|
||||
'../mojo_variables.gypi',
|
||||
],
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'mojo_edk_tests',
|
||||
'type': 'none',
|
||||
'dependencies': [
|
||||
# NOTE: If adding a new dependency here, please consider whether it
|
||||
# should also be added to the list of Mojo-related dependencies of
|
||||
# build/all.gyp:All on iOS, as All cannot depend on the mojo_base
|
||||
# target on iOS due to the presence of the js targets, which cause v8
|
||||
# to be built.
|
||||
'mojo_message_pipe_perftests',
|
||||
'mojo_public_application_unittests',
|
||||
'mojo_public_bindings_unittests',
|
||||
'mojo_public_environment_unittests',
|
||||
'mojo_public_system_perftests',
|
||||
'mojo_public_system_unittests',
|
||||
'mojo_public_utility_unittests',
|
||||
'mojo_system_unittests',
|
||||
'mojo_js_unittests',
|
||||
'mojo_js_integration_tests',
|
||||
],
|
||||
},
|
||||
# TODO(vtl): Reorganize the mojo_public_*_unittests.
|
||||
{
|
||||
# GN version: //mojo/public/cpp/bindings/tests:mojo_public_bindings_unittests
|
||||
'target_name': 'mojo_public_bindings_unittests',
|
||||
'type': 'executable',
|
||||
'dependencies': [
|
||||
'../../testing/gtest.gyp:gtest',
|
||||
'mojo_edk.gyp:mojo_run_all_unittests',
|
||||
'../public/mojo_public.gyp:mojo_cpp_bindings',
|
||||
'../public/mojo_public.gyp:mojo_environment_standalone',
|
||||
'../public/mojo_public.gyp:mojo_public_bindings_test_utils',
|
||||
'../public/mojo_public.gyp:mojo_public_test_interfaces',
|
||||
'../public/mojo_public.gyp:mojo_public_test_utils',
|
||||
'../public/mojo_public.gyp:mojo_utility',
|
||||
],
|
||||
'sources': [
|
||||
'../public/cpp/bindings/tests/array_unittest.cc',
|
||||
'../public/cpp/bindings/tests/bounds_checker_unittest.cc',
|
||||
'../public/cpp/bindings/tests/buffer_unittest.cc',
|
||||
'../public/cpp/bindings/tests/connector_unittest.cc',
|
||||
'../public/cpp/bindings/tests/container_test_util.cc',
|
||||
'../public/cpp/bindings/tests/equals_unittest.cc',
|
||||
'../public/cpp/bindings/tests/handle_passing_unittest.cc',
|
||||
'../public/cpp/bindings/tests/interface_ptr_unittest.cc',
|
||||
'../public/cpp/bindings/tests/map_unittest.cc',
|
||||
'../public/cpp/bindings/tests/request_response_unittest.cc',
|
||||
'../public/cpp/bindings/tests/router_unittest.cc',
|
||||
'../public/cpp/bindings/tests/sample_service_unittest.cc',
|
||||
'../public/cpp/bindings/tests/serialization_warning_unittest.cc',
|
||||
'../public/cpp/bindings/tests/string_unittest.cc',
|
||||
'../public/cpp/bindings/tests/struct_unittest.cc',
|
||||
'../public/cpp/bindings/tests/type_conversion_unittest.cc',
|
||||
'../public/cpp/bindings/tests/validation_unittest.cc',
|
||||
],
|
||||
},
|
||||
{
|
||||
# GN version: //mojo/public/cpp/environment/tests:mojo_public_environment_unittests
|
||||
'target_name': 'mojo_public_environment_unittests',
|
||||
'type': 'executable',
|
||||
'dependencies': [
|
||||
'../../testing/gtest.gyp:gtest',
|
||||
'mojo_edk.gyp:mojo_run_all_unittests',
|
||||
'../public/mojo_public.gyp:mojo_environment_standalone',
|
||||
'../public/mojo_public.gyp:mojo_public_test_utils',
|
||||
'../public/mojo_public.gyp:mojo_utility',
|
||||
],
|
||||
'include_dirs': [ '../..' ],
|
||||
'sources': [
|
||||
'../public/cpp/environment/tests/async_wait_unittest.cc',
|
||||
'../public/cpp/environment/tests/async_waiter_unittest.cc',
|
||||
'../public/cpp/environment/tests/logger_unittest.cc',
|
||||
'../public/cpp/environment/tests/logging_unittest.cc',
|
||||
],
|
||||
},
|
||||
{
|
||||
# GN version: //mojo/public/cpp/application/tests:mojo_public_application_unittests
|
||||
'target_name': 'mojo_public_application_unittests',
|
||||
'type': 'executable',
|
||||
'dependencies': [
|
||||
'../../base/base.gyp:base',
|
||||
'../../testing/gtest.gyp:gtest',
|
||||
'mojo_edk.gyp:mojo_run_all_unittests',
|
||||
'../public/mojo_public.gyp:mojo_application_standalone',
|
||||
'../public/mojo_public.gyp:mojo_utility',
|
||||
'../public/mojo_public.gyp:mojo_environment_standalone',
|
||||
],
|
||||
'sources': [
|
||||
'../public/cpp/application/tests/service_registry_unittest.cc',
|
||||
],
|
||||
},
|
||||
{
|
||||
# GN version: //mojo/public/cpp/system/tests:mojo_public_system_unittests
|
||||
# and //mojo/public/c/system/tests
|
||||
'target_name': 'mojo_public_system_unittests',
|
||||
'type': 'executable',
|
||||
'dependencies': [
|
||||
'../../testing/gtest.gyp:gtest',
|
||||
'mojo_edk.gyp:mojo_run_all_unittests',
|
||||
'../public/mojo_public.gyp:mojo_public_test_utils',
|
||||
],
|
||||
'include_dirs': [ '../..' ],
|
||||
'sources': [
|
||||
'<@(mojo_public_system_unittest_sources)',
|
||||
],
|
||||
},
|
||||
{
|
||||
# GN version: //mojo/public/cpp/application/tests:mojo_public_utility_unittests
|
||||
'target_name': 'mojo_public_utility_unittests',
|
||||
'type': 'executable',
|
||||
'dependencies': [
|
||||
'../../testing/gtest.gyp:gtest',
|
||||
'mojo_edk.gyp:mojo_run_all_unittests',
|
||||
'../public/mojo_public.gyp:mojo_public_test_utils',
|
||||
'../public/mojo_public.gyp:mojo_utility',
|
||||
],
|
||||
'include_dirs': [ '../..' ],
|
||||
'sources': [
|
||||
'../public/cpp/utility/tests/mutex_unittest.cc',
|
||||
'../public/cpp/utility/tests/run_loop_unittest.cc',
|
||||
'../public/cpp/utility/tests/thread_unittest.cc',
|
||||
],
|
||||
'conditions': [
|
||||
# See crbug.com/342893:
|
||||
['OS=="win"', {
|
||||
'sources!': [
|
||||
'../public/cpp/utility/tests/mutex_unittest.cc',
|
||||
'../public/cpp/utility/tests/thread_unittest.cc',
|
||||
],
|
||||
}],
|
||||
],
|
||||
},
|
||||
{
|
||||
# GN version: //mojo/public/c/system/tests:perftests
|
||||
'target_name': 'mojo_public_system_perftests',
|
||||
'type': 'executable',
|
||||
'dependencies': [
|
||||
'../../base/base.gyp:base',
|
||||
'../../testing/gtest.gyp:gtest',
|
||||
'mojo_edk.gyp:mojo_run_all_perftests',
|
||||
'../public/mojo_public.gyp:mojo_public_test_utils',
|
||||
'../public/mojo_public.gyp:mojo_utility',
|
||||
],
|
||||
'sources': [
|
||||
'../public/c/system/tests/core_perftest.cc',
|
||||
],
|
||||
},
|
||||
{
|
||||
# GN version: //mojo/edk/system:mojo_system_unittests
|
||||
'target_name': 'mojo_system_unittests',
|
||||
'type': 'executable',
|
||||
'dependencies': [
|
||||
'../../base/base.gyp:base',
|
||||
'../../testing/gtest.gyp:gtest',
|
||||
'mojo_edk.gyp:mojo_common_test_support',
|
||||
'mojo_edk.gyp:mojo_system_impl',
|
||||
],
|
||||
'sources': [
|
||||
'embedder/embedder_unittest.cc',
|
||||
'embedder/platform_channel_pair_posix_unittest.cc',
|
||||
'embedder/simple_platform_shared_buffer_unittest.cc',
|
||||
'system/channel_endpoint_id_unittest.cc',
|
||||
'system/channel_unittest.cc',
|
||||
'system/core_unittest.cc',
|
||||
'system/core_test_base.cc',
|
||||
'system/core_test_base.h',
|
||||
'system/data_pipe_unittest.cc',
|
||||
'system/dispatcher_unittest.cc',
|
||||
'system/local_data_pipe_unittest.cc',
|
||||
'system/memory_unittest.cc',
|
||||
'system/message_pipe_dispatcher_unittest.cc',
|
||||
'system/message_pipe_test_utils.h',
|
||||
'system/message_pipe_test_utils.cc',
|
||||
'system/message_pipe_unittest.cc',
|
||||
'system/multiprocess_message_pipe_unittest.cc',
|
||||
'system/options_validation_unittest.cc',
|
||||
'system/platform_handle_dispatcher_unittest.cc',
|
||||
'system/raw_channel_unittest.cc',
|
||||
'system/remote_message_pipe_unittest.cc',
|
||||
'system/run_all_unittests.cc',
|
||||
'system/shared_buffer_dispatcher_unittest.cc',
|
||||
'system/simple_dispatcher_unittest.cc',
|
||||
'system/test_utils.cc',
|
||||
'system/test_utils.h',
|
||||
'system/waiter_list_unittest.cc',
|
||||
'system/waiter_test_utils.cc',
|
||||
'system/waiter_test_utils.h',
|
||||
'system/waiter_unittest.cc',
|
||||
'test/multiprocess_test_helper_unittest.cc',
|
||||
],
|
||||
'conditions': [
|
||||
['OS=="ios"', {
|
||||
'sources!': [
|
||||
'embedder/embedder_unittest.cc',
|
||||
'system/multiprocess_message_pipe_unittest.cc',
|
||||
'test/multiprocess_test_helper_unittest.cc',
|
||||
],
|
||||
}],
|
||||
],
|
||||
},
|
||||
{
|
||||
# GN version: //mojo/edk/system:mojo_message_pipe_perftests
|
||||
'target_name': 'mojo_message_pipe_perftests',
|
||||
'type': 'executable',
|
||||
'dependencies': [
|
||||
'../../base/base.gyp:base',
|
||||
'../../base/base.gyp:test_support_base',
|
||||
'../../base/base.gyp:test_support_perf',
|
||||
'../../testing/gtest.gyp:gtest',
|
||||
'mojo_edk.gyp:mojo_common_test_support',
|
||||
'mojo_edk.gyp:mojo_system_impl',
|
||||
],
|
||||
'sources': [
|
||||
'system/message_pipe_perftest.cc',
|
||||
'system/message_pipe_test_utils.h',
|
||||
'system/message_pipe_test_utils.cc',
|
||||
'system/test_utils.cc',
|
||||
'system/test_utils.h',
|
||||
],
|
||||
},
|
||||
{
|
||||
# GN version: //mojo/edk/js/test:js_unittests
|
||||
'target_name': 'mojo_js_unittests',
|
||||
'type': 'executable',
|
||||
'dependencies': [
|
||||
'../../gin/gin.gyp:gin_test',
|
||||
'mojo_edk.gyp:mojo_common_test_support',
|
||||
'mojo_edk.gyp:mojo_run_all_unittests',
|
||||
'mojo_edk.gyp:mojo_js_lib',
|
||||
'../public/mojo_public.gyp:mojo_environment_standalone',
|
||||
'../public/mojo_public.gyp:mojo_public_test_interfaces',
|
||||
'../public/mojo_public.gyp:mojo_utility',
|
||||
],
|
||||
'sources': [
|
||||
'js/handle_unittest.cc',
|
||||
'js/test/run_js_tests.cc',
|
||||
],
|
||||
},
|
||||
{
|
||||
# GN version: //mojo/edk/js/test:js_integration_tests
|
||||
'target_name': 'mojo_js_integration_tests',
|
||||
'type': 'executable',
|
||||
'dependencies': [
|
||||
'../../base/base.gyp:base',
|
||||
'../../gin/gin.gyp:gin_test',
|
||||
'../public/mojo_public.gyp:mojo_environment_standalone',
|
||||
'../public/mojo_public.gyp:mojo_public_test_interfaces',
|
||||
'../public/mojo_public.gyp:mojo_utility',
|
||||
'mojo_edk.gyp:mojo_js_lib',
|
||||
'mojo_edk.gyp:mojo_run_all_unittests',
|
||||
'mojo_js_to_cpp_bindings',
|
||||
],
|
||||
'sources': [
|
||||
'js/test/run_js_integration_tests.cc',
|
||||
'js/tests/js_to_cpp_tests',
|
||||
],
|
||||
},
|
||||
{
|
||||
'target_name': 'mojo_js_to_cpp_bindings',
|
||||
'type': 'none',
|
||||
'variables': {
|
||||
'mojom_files': [
|
||||
'js/tests/js_to_cpp.mojom',
|
||||
],
|
||||
},
|
||||
'includes': [ '../public/tools/bindings/mojom_bindings_generator_explicit.gypi' ],
|
||||
},
|
||||
],
|
||||
}
|
@ -12,19 +12,6 @@ config("system_config") {
|
||||
component("system") {
|
||||
output_name = "mojo_system_impl"
|
||||
|
||||
deps = [
|
||||
"//base",
|
||||
"//base/third_party/dynamic_annotations",
|
||||
"//mojo/edk/embedder",
|
||||
]
|
||||
|
||||
defines = [
|
||||
"MOJO_SYSTEM_IMPL_IMPLEMENTATION",
|
||||
"MOJO_SYSTEM_IMPLEMENTATION",
|
||||
]
|
||||
|
||||
all_dependent_configs = [ ":system_config" ]
|
||||
|
||||
sources = [
|
||||
"channel.cc",
|
||||
"channel.h",
|
||||
@ -34,7 +21,10 @@ component("system") {
|
||||
"channel_endpoint_id.h",
|
||||
"channel_info.cc",
|
||||
"channel_info.h",
|
||||
"constants.h",
|
||||
"channel_manager.cc",
|
||||
"channel_manager.h",
|
||||
"configuration.cc",
|
||||
"configuration.h",
|
||||
"core.cc",
|
||||
"core.h",
|
||||
"data_pipe.cc",
|
||||
@ -45,7 +35,6 @@ component("system") {
|
||||
"data_pipe_producer_dispatcher.h",
|
||||
"dispatcher.cc",
|
||||
"dispatcher.h",
|
||||
"entrypoints.cc",
|
||||
"handle_signals_state.h",
|
||||
"handle_table.cc",
|
||||
"handle_table.h",
|
||||
@ -87,18 +76,30 @@ component("system") {
|
||||
"waiter_list.cc",
|
||||
"waiter_list.h",
|
||||
]
|
||||
|
||||
defines = [
|
||||
"MOJO_SYSTEM_IMPL_IMPLEMENTATION",
|
||||
"MOJO_SYSTEM_IMPLEMENTATION",
|
||||
]
|
||||
|
||||
all_dependent_configs = [ ":system_config" ]
|
||||
|
||||
public_deps = [
|
||||
"//mojo/edk/embedder",
|
||||
"//mojo/edk/embedder:platform",
|
||||
"//mojo/public/c/system",
|
||||
]
|
||||
|
||||
deps = [
|
||||
"//base",
|
||||
"//base/third_party/dynamic_annotations",
|
||||
]
|
||||
|
||||
allow_circular_includes_from = [ "//mojo/edk/embedder" ]
|
||||
}
|
||||
|
||||
# GYP version: mojo/edk/mojo_edk.gyp:mojo_system_unittests
|
||||
test("mojo_system_unittests") {
|
||||
deps = [
|
||||
":system",
|
||||
"//base",
|
||||
"//mojo/edk/embedder:embedder_unittests",
|
||||
"//mojo/edk/test:test_support",
|
||||
"//testing/gtest",
|
||||
]
|
||||
|
||||
sources = [
|
||||
"../test/multiprocess_test_helper_unittest.cc",
|
||||
"channel_endpoint_id_unittest.cc",
|
||||
@ -122,6 +123,7 @@ test("mojo_system_unittests") {
|
||||
"run_all_unittests.cc",
|
||||
"shared_buffer_dispatcher_unittest.cc",
|
||||
"simple_dispatcher_unittest.cc",
|
||||
# TODO(vtl): Factor test_utils.* into their own source set.
|
||||
"test_utils.cc",
|
||||
"test_utils.h",
|
||||
"waiter_list_unittest.cc",
|
||||
@ -129,10 +131,29 @@ test("mojo_system_unittests") {
|
||||
"waiter_test_utils.h",
|
||||
"waiter_unittest.cc",
|
||||
]
|
||||
|
||||
deps = [
|
||||
":system",
|
||||
"//base",
|
||||
"//base/test:test_support",
|
||||
"//mojo/edk/embedder:embedder_unittests",
|
||||
"//mojo/edk/test:test_support",
|
||||
"//testing/gtest",
|
||||
]
|
||||
|
||||
allow_circular_includes_from = [ "//mojo/edk/embedder:embedder_unittests" ]
|
||||
}
|
||||
|
||||
# GYP version: mojo/edk/mojo_edk.gyp:mojo_message_pipe_perftests
|
||||
test("mojo_message_pipe_perftests") {
|
||||
sources = [
|
||||
"message_pipe_perftest.cc",
|
||||
"message_pipe_test_utils.h",
|
||||
"message_pipe_test_utils.cc",
|
||||
"test_utils.cc",
|
||||
"test_utils.h",
|
||||
]
|
||||
|
||||
deps = [
|
||||
":system",
|
||||
"//base",
|
||||
@ -141,12 +162,4 @@ test("mojo_message_pipe_perftests") {
|
||||
"//mojo/edk/test:test_support",
|
||||
"//testing/gtest",
|
||||
]
|
||||
|
||||
sources = [
|
||||
"message_pipe_perftest.cc",
|
||||
"message_pipe_test_utils.h",
|
||||
"message_pipe_test_utils.cc",
|
||||
"test_utils.cc",
|
||||
"test_utils.h",
|
||||
]
|
||||
}
|
||||
|
@ -20,7 +20,8 @@ namespace system {
|
||||
Channel::Channel(embedder::PlatformSupport* platform_support)
|
||||
: platform_support_(platform_support),
|
||||
is_running_(false),
|
||||
is_shutting_down_(false) {
|
||||
is_shutting_down_(false),
|
||||
channel_manager_(nullptr) {
|
||||
}
|
||||
|
||||
bool Channel::Init(scoped_ptr<RawChannel> raw_channel) {
|
||||
@ -41,6 +42,15 @@ bool Channel::Init(scoped_ptr<RawChannel> raw_channel) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void Channel::SetChannelManager(ChannelManager* channel_manager) {
|
||||
DCHECK(channel_manager);
|
||||
|
||||
base::AutoLock locker(lock_);
|
||||
DCHECK(!is_shutting_down_);
|
||||
DCHECK(!channel_manager_);
|
||||
channel_manager_ = channel_manager;
|
||||
}
|
||||
|
||||
void Channel::Shutdown() {
|
||||
DCHECK(creation_thread_checker_.CalledOnValidThread());
|
||||
|
||||
@ -62,8 +72,7 @@ void Channel::Shutdown() {
|
||||
size_t num_live = 0;
|
||||
size_t num_zombies = 0;
|
||||
for (IdToEndpointMap::iterator it = to_destroy.begin();
|
||||
it != to_destroy.end();
|
||||
++it) {
|
||||
it != to_destroy.end(); ++it) {
|
||||
if (it->second.get()) {
|
||||
num_live++;
|
||||
it->second->OnDisconnect();
|
||||
@ -80,6 +89,7 @@ void Channel::Shutdown() {
|
||||
void Channel::WillShutdownSoon() {
|
||||
base::AutoLock locker(lock_);
|
||||
is_shutting_down_ = true;
|
||||
channel_manager_ = nullptr;
|
||||
}
|
||||
|
||||
// Note: |endpoint| being a |scoped_refptr| makes this function safe, since it
|
||||
@ -120,8 +130,7 @@ ChannelEndpointId Channel::AttachAndRunEndpoint(
|
||||
|
||||
if (!is_bootstrap) {
|
||||
if (!SendControlMessage(
|
||||
MessageInTransit::kSubtypeChannelAttachAndRunEndpoint,
|
||||
local_id,
|
||||
MessageInTransit::kSubtypeChannelAttachAndRunEndpoint, local_id,
|
||||
remote_id)) {
|
||||
HandleLocalError(base::StringPrintf(
|
||||
"Failed to send message to run remote message pipe endpoint (local "
|
||||
@ -185,8 +194,7 @@ void Channel::DetachEndpoint(ChannelEndpoint* endpoint,
|
||||
}
|
||||
|
||||
if (!SendControlMessage(
|
||||
MessageInTransit::kSubtypeChannelRemoveMessagePipeEndpoint,
|
||||
local_id,
|
||||
MessageInTransit::kSubtypeChannelRemoveMessagePipeEndpoint, local_id,
|
||||
remote_id)) {
|
||||
HandleLocalError(base::StringPrintf(
|
||||
"Failed to send message to remove remote message pipe endpoint (local "
|
||||
@ -207,7 +215,7 @@ scoped_refptr<MessagePipe> Channel::PassIncomingMessagePipe(
|
||||
|
||||
auto it = incoming_message_pipes_.find(local_id);
|
||||
if (it == incoming_message_pipes_.end())
|
||||
return scoped_refptr<MessagePipe>();
|
||||
return nullptr;
|
||||
|
||||
scoped_refptr<MessagePipe> rv;
|
||||
rv.swap(it->second);
|
||||
@ -459,8 +467,7 @@ bool Channel::OnRemoveMessagePipeEndpoint(ChannelEndpointId local_id,
|
||||
|
||||
if (!SendControlMessage(
|
||||
MessageInTransit::kSubtypeChannelRemoveMessagePipeEndpointAck,
|
||||
local_id,
|
||||
remote_id)) {
|
||||
local_id, remote_id)) {
|
||||
HandleLocalError(base::StringPrintf(
|
||||
"Failed to send message to remove remote message pipe endpoint ack "
|
||||
"(local ID %u, remote ID %u)",
|
||||
|
@ -32,6 +32,7 @@ class PlatformSupport;
|
||||
namespace system {
|
||||
|
||||
class ChannelEndpoint;
|
||||
class ChannelManager;
|
||||
|
||||
// This class is mostly thread-safe. It must be created on an I/O thread.
|
||||
// |Init()| must be called on that same thread before it becomes thread-safe (in
|
||||
@ -61,6 +62,11 @@ class MOJO_SYSTEM_IMPL_EXPORT Channel
|
||||
// failure, no other methods should be called (including |Shutdown()|).
|
||||
bool Init(scoped_ptr<RawChannel> raw_channel);
|
||||
|
||||
// Sets the channel manager associated with this channel. This should be set
|
||||
// at most once and only called before |WillShutdownSoon()| (and
|
||||
// |Shutdown()|).
|
||||
void SetChannelManager(ChannelManager* channel_manager);
|
||||
|
||||
// This must be called on the creation thread before destruction (which can
|
||||
// happen on any thread).
|
||||
void Shutdown();
|
||||
@ -69,6 +75,8 @@ class MOJO_SYSTEM_IMPL_EXPORT Channel
|
||||
// thread, unlike |Shutdown()|). Warnings will be issued if, e.g., messages
|
||||
// are written after this is called; other warnings may be suppressed. (This
|
||||
// may be called multiple times, or not at all.)
|
||||
//
|
||||
// If set, the channel manager associated with this channel will be reset.
|
||||
void WillShutdownSoon();
|
||||
|
||||
// Attaches the given endpoint to this channel and runs it. |is_bootstrap|
|
||||
@ -175,6 +183,9 @@ class MOJO_SYSTEM_IMPL_EXPORT Channel
|
||||
// Set when |WillShutdownSoon()| is called.
|
||||
bool is_shutting_down_;
|
||||
|
||||
// Has a reference to us.
|
||||
ChannelManager* channel_manager_;
|
||||
|
||||
typedef base::hash_map<ChannelEndpointId, scoped_refptr<ChannelEndpoint>>
|
||||
IdToEndpointMap;
|
||||
// Map from local IDs to endpoints. If the endpoint is null, this means that
|
||||
|
@ -109,8 +109,7 @@ bool ChannelEndpoint::OnReadMessage(
|
||||
DCHECK(message_view.transport_data_buffer());
|
||||
message->SetDispatchers(TransportData::DeserializeDispatchers(
|
||||
message_view.transport_data_buffer(),
|
||||
message_view.transport_data_buffer_size(),
|
||||
platform_handles.Pass(),
|
||||
message_view.transport_data_buffer_size(), platform_handles.Pass(),
|
||||
channel_));
|
||||
}
|
||||
|
||||
|
@ -26,13 +26,13 @@ class MessagePipe;
|
||||
// refcounted, and not copyable. Make |Channel| a friend. Make things work.
|
||||
// - (Done.) Give |ChannelEndpoint| a lock. The lock order (in order of
|
||||
// allowable acquisition) is: |MessagePipe|, |ChannelEndpoint|, |Channel|.
|
||||
// - Stop having |Channel| as a friend.
|
||||
// - Move logic from |ProxyMessagePipeEndpoint| into |ChannelEndpoint|. Right
|
||||
// now, we have to go through lots of contortions to manipulate state owned
|
||||
// by |ProxyMessagePipeEndpoint| (in particular, |Channel::Endpoint| doesn't
|
||||
// know about the remote ID; the local ID is duplicated in two places).
|
||||
// Hollow out |ProxyMessagePipeEndpoint|, and have it just own a reference
|
||||
// to |ChannelEndpoint| (hence the refcounting).
|
||||
// - (Done) Stop having |Channel| as a friend.
|
||||
// - (Done) Move logic from |ProxyMessagePipeEndpoint| into |ChannelEndpoint|.
|
||||
// Right now, we have to go through lots of contortions to manipulate state
|
||||
// owned by |ProxyMessagePipeEndpoint| (in particular, |Channel::Endpoint|
|
||||
// doesn't know about the remote ID; the local ID is duplicated in two
|
||||
// places). Hollow out |ProxyMessagePipeEndpoint|, and have it just own a
|
||||
// reference to |ChannelEndpoint| (hence the refcounting).
|
||||
// - In essence, |ChannelEndpoint| becomes the thing that knows about
|
||||
// channel-specific aspects of an endpoint (notably local and remote IDs,
|
||||
// and knowledge about handshaking), and mediates between the |Channel| and
|
||||
|
@ -4,6 +4,8 @@
|
||||
|
||||
#include "mojo/edk/system/channel_info.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace mojo {
|
||||
namespace system {
|
||||
|
||||
@ -19,5 +21,11 @@ ChannelInfo::ChannelInfo(
|
||||
ChannelInfo::~ChannelInfo() {
|
||||
}
|
||||
|
||||
void ChannelInfo::Swap(ChannelInfo* other) {
|
||||
// Note: Swapping avoids refcount churn.
|
||||
std::swap(channel, other->channel);
|
||||
std::swap(channel_thread_task_runner, other->channel_thread_task_runner);
|
||||
}
|
||||
|
||||
} // namespace system
|
||||
} // namespace mojo
|
||||
|
@ -19,6 +19,8 @@ struct MOJO_SYSTEM_IMPL_EXPORT ChannelInfo {
|
||||
scoped_refptr<base::TaskRunner> channel_thread_task_runner);
|
||||
~ChannelInfo();
|
||||
|
||||
void Swap(ChannelInfo* other);
|
||||
|
||||
scoped_refptr<Channel> channel;
|
||||
// The task runner for |channel|'s creation thread (a.k.a. its I/O thread), on
|
||||
// which it must, e.g., be shut down.
|
||||
|
78
mojo/edk/system/channel_manager.cc
Normal file
78
mojo/edk/system/channel_manager.cc
Normal file
@ -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/edk/system/channel_manager.h"
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "base/location.h"
|
||||
#include "base/message_loop/message_loop_proxy.h"
|
||||
|
||||
namespace mojo {
|
||||
namespace system {
|
||||
|
||||
namespace {
|
||||
|
||||
void ShutdownChannelHelper(const ChannelInfo& channel_info) {
|
||||
if (base::MessageLoopProxy::current() ==
|
||||
channel_info.channel_thread_task_runner) {
|
||||
channel_info.channel->Shutdown();
|
||||
} else {
|
||||
channel_info.channel->WillShutdownSoon();
|
||||
channel_info.channel_thread_task_runner->PostTask(
|
||||
FROM_HERE, base::Bind(&Channel::Shutdown, channel_info.channel));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
ChannelManager::ChannelManager() {
|
||||
}
|
||||
|
||||
ChannelManager::~ChannelManager() {
|
||||
// No need to take the lock.
|
||||
for (const auto& map_elem : channel_infos_)
|
||||
ShutdownChannelHelper(map_elem.second);
|
||||
}
|
||||
|
||||
ChannelId ChannelManager::AddChannel(
|
||||
scoped_refptr<Channel> channel,
|
||||
scoped_refptr<base::TaskRunner> channel_thread_task_runner) {
|
||||
ChannelId channel_id = GetChannelId(channel.get());
|
||||
|
||||
{
|
||||
base::AutoLock locker(lock_);
|
||||
DCHECK(channel_infos_.find(channel_id) == channel_infos_.end());
|
||||
channel_infos_[channel_id] =
|
||||
ChannelInfo(channel, channel_thread_task_runner);
|
||||
}
|
||||
channel->SetChannelManager(this);
|
||||
|
||||
return channel_id;
|
||||
}
|
||||
|
||||
void ChannelManager::WillShutdownChannel(ChannelId channel_id) {
|
||||
GetChannelInfo(channel_id).channel->WillShutdownSoon();
|
||||
}
|
||||
|
||||
void ChannelManager::ShutdownChannel(ChannelId channel_id) {
|
||||
ChannelInfo channel_info;
|
||||
{
|
||||
base::AutoLock locker(lock_);
|
||||
auto it = channel_infos_.find(channel_id);
|
||||
DCHECK(it != channel_infos_.end());
|
||||
channel_info.Swap(&it->second);
|
||||
channel_infos_.erase(it);
|
||||
}
|
||||
ShutdownChannelHelper(channel_info);
|
||||
}
|
||||
|
||||
ChannelInfo ChannelManager::GetChannelInfo(ChannelId channel_id) {
|
||||
base::AutoLock locker(lock_);
|
||||
auto it = channel_infos_.find(channel_id);
|
||||
DCHECK(it != channel_infos_.end());
|
||||
return it->second;
|
||||
}
|
||||
|
||||
} // namespace system
|
||||
} // namespace mojo
|
83
mojo/edk/system/channel_manager.h
Normal file
83
mojo/edk/system/channel_manager.h
Normal file
@ -0,0 +1,83 @@
|
||||
// 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_SYSTEM_CHANNEL_MANAGER_H_
|
||||
#define MOJO_EDK_SYSTEM_CHANNEL_MANAGER_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "base/containers/hash_tables.h"
|
||||
#include "base/macros.h"
|
||||
#include "base/memory/ref_counted.h"
|
||||
#include "base/synchronization/lock.h"
|
||||
#include "base/task_runner.h"
|
||||
#include "mojo/edk/system/channel.h"
|
||||
#include "mojo/edk/system/channel_info.h"
|
||||
|
||||
namespace mojo {
|
||||
namespace system {
|
||||
|
||||
// IDs for |Channel|s managed by a |ChannelManager|. (IDs should be thought of
|
||||
// as specific to a given |ChannelManager|.) 0 is never a valid ID.
|
||||
//
|
||||
// Note: We currently just use the pointer of the |Channel| casted to a
|
||||
// |uintptr_t|, but we reserve the right to change this.
|
||||
typedef uintptr_t ChannelId;
|
||||
|
||||
// This class manages and "owns" |Channel|s (which typically connect to other
|
||||
// processes) for a given process. This class is thread-safe.
|
||||
class MOJO_SYSTEM_IMPL_EXPORT ChannelManager {
|
||||
public:
|
||||
ChannelManager();
|
||||
~ChannelManager();
|
||||
|
||||
// Gets the ID for a given channel.
|
||||
//
|
||||
// Note: This is currently a static method and thus may be called under
|
||||
// |lock_|. If this is ever made non-static (i.e., made specific to a given
|
||||
// |ChannelManager|), those call sites may have to changed.
|
||||
static ChannelId GetChannelId(const Channel* channel) {
|
||||
return reinterpret_cast<ChannelId>(channel);
|
||||
}
|
||||
|
||||
// Adds |channel| to the set of |Channel|s managed by this |ChannelManager|;
|
||||
// |channel_thread_task_runner| should be the task runner for |channel|'s
|
||||
// creation (a.k.a. I/O) thread. |channel| should either already be
|
||||
// initialized. It should not be managed by any |ChannelManager| yet. Returns
|
||||
// the ID for the added channel.
|
||||
ChannelId AddChannel(
|
||||
scoped_refptr<Channel> channel,
|
||||
scoped_refptr<base::TaskRunner> channel_thread_task_runner);
|
||||
|
||||
// Informs the channel manager (and thus channel) that it will be shutdown
|
||||
// soon (by calling |ShutdownChannel()|). Calling this is optional (and may in
|
||||
// fact be called multiple times) but it will suppress certain warnings (e.g.,
|
||||
// for the channel being broken) and enable others (if messages are written to
|
||||
// the channel).
|
||||
void WillShutdownChannel(ChannelId channel_id);
|
||||
|
||||
// Shuts down the channel specified by the given ID. It is up to the caller to
|
||||
// guarantee that this is only called once per channel (that was added using
|
||||
// |AddChannel()|). If called from the chanel's creation thread (i.e.,
|
||||
// |base::MessageLoopProxy::current()| is the channel thread's |TaskRunner|),
|
||||
// this will complete synchronously.
|
||||
void ShutdownChannel(ChannelId channel_id);
|
||||
|
||||
private:
|
||||
// Gets the |ChannelInfo| for the channel specified by the given ID. (This
|
||||
// should *not* be called under lock.)
|
||||
ChannelInfo GetChannelInfo(ChannelId channel_id);
|
||||
|
||||
// Note: |Channel| methods should not be called under |lock_|.
|
||||
base::Lock lock_; // Protects the members below.
|
||||
|
||||
base::hash_map<ChannelId, ChannelInfo> channel_infos_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ChannelManager);
|
||||
};
|
||||
|
||||
} // namespace system
|
||||
} // namespace mojo
|
||||
|
||||
#endif // MOJO_EDK_SYSTEM_CHANNEL_MANAGER_H_
|
@ -104,9 +104,8 @@ TEST_F(ChannelTest, InitShutdown) {
|
||||
EXPECT_EQ(TRISTATE_TRUE, init_result());
|
||||
|
||||
io_thread()->PostTaskAndWait(
|
||||
FROM_HERE,
|
||||
base::Bind(&ChannelTest::ShutdownChannelOnIOThread,
|
||||
base::Unretained(this)));
|
||||
FROM_HERE, base::Bind(&ChannelTest::ShutdownChannelOnIOThread,
|
||||
base::Unretained(this)));
|
||||
|
||||
// Okay to destroy |Channel| on not-the-I/O-thread.
|
||||
EXPECT_TRUE(channel()->HasOneRef());
|
||||
@ -203,9 +202,8 @@ TEST_F(ChannelTest, CloseBeforeRun) {
|
||||
channel()->AttachAndRunEndpoint(channel_endpoint, true);
|
||||
|
||||
io_thread()->PostTaskAndWait(
|
||||
FROM_HERE,
|
||||
base::Bind(&ChannelTest::ShutdownChannelOnIOThread,
|
||||
base::Unretained(this)));
|
||||
FROM_HERE, base::Bind(&ChannelTest::ShutdownChannelOnIOThread,
|
||||
base::Unretained(this)));
|
||||
|
||||
EXPECT_TRUE(channel()->HasOneRef());
|
||||
}
|
||||
@ -273,9 +271,8 @@ TEST_F(ChannelTest, WaitAfterAttachRunAndShutdown) {
|
||||
channel()->AttachAndRunEndpoint(channel_endpoint, true);
|
||||
|
||||
io_thread()->PostTaskAndWait(
|
||||
FROM_HERE,
|
||||
base::Bind(&ChannelTest::ShutdownChannelOnIOThread,
|
||||
base::Unretained(this)));
|
||||
FROM_HERE, base::Bind(&ChannelTest::ShutdownChannelOnIOThread,
|
||||
base::Unretained(this)));
|
||||
|
||||
Waiter waiter;
|
||||
waiter.Init();
|
||||
|
26
mojo/edk/system/configuration.cc
Normal file
26
mojo/edk/system/configuration.cc
Normal file
@ -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/edk/system/configuration.h"
|
||||
|
||||
namespace mojo {
|
||||
namespace system {
|
||||
namespace internal {
|
||||
|
||||
// These default values should be synced with the documentation in
|
||||
// mojo/edk/embedder/configuration.h.
|
||||
embedder::Configuration g_configuration = {
|
||||
1000000, // max_handle_table_size
|
||||
1000000, // max_mapping_table_sze
|
||||
1000000, // max_wait_many_num_handles
|
||||
4 * 1024 * 1024, // max_message_num_bytes
|
||||
10000, // max_message_num_handles
|
||||
256 * 1024 * 1024, // max_data_pipe_capacity_bytes
|
||||
1024 * 1024, // default_data_pipe_capacity_bytes
|
||||
16, // data_pipe_buffer_alignment_bytes
|
||||
1024 * 1024 * 1024}; // max_shared_memory_num_bytes
|
||||
|
||||
} // namespace internal
|
||||
} // namespace system
|
||||
} // namespace mojo
|
31
mojo/edk/system/configuration.h
Normal file
31
mojo/edk/system/configuration.h
Normal file
@ -0,0 +1,31 @@
|
||||
// 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_SYSTEM_CONFIGURATION_H_
|
||||
#define MOJO_EDK_SYSTEM_CONFIGURATION_H_
|
||||
|
||||
#include "mojo/edk/embedder/configuration.h"
|
||||
#include "mojo/edk/system/system_impl_export.h"
|
||||
|
||||
namespace mojo {
|
||||
namespace system {
|
||||
|
||||
namespace internal {
|
||||
MOJO_SYSTEM_IMPL_EXPORT extern embedder::Configuration g_configuration;
|
||||
} // namespace internal
|
||||
|
||||
MOJO_SYSTEM_IMPL_EXPORT inline const embedder::Configuration&
|
||||
GetConfiguration() {
|
||||
return internal::g_configuration;
|
||||
}
|
||||
|
||||
MOJO_SYSTEM_IMPL_EXPORT inline embedder::Configuration*
|
||||
GetMutableConfiguration() {
|
||||
return &internal::g_configuration;
|
||||
}
|
||||
|
||||
} // namespace system
|
||||
} // namespace mojo
|
||||
|
||||
#endif // MOJO_EDK_SYSTEM_CONFIGURATION_H_
|
@ -1,48 +0,0 @@
|
||||
// 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_EDK_SYSTEM_CONSTANTS_H_
|
||||
#define MOJO_EDK_SYSTEM_CONSTANTS_H_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
namespace mojo {
|
||||
namespace system {
|
||||
|
||||
// Maximum number of open (Mojo) handles.
|
||||
// TODO(vtl): This doesn't count "live" handles, some of which may live in
|
||||
// messages.
|
||||
const size_t kMaxHandleTableSize = 1000000;
|
||||
|
||||
// Maximum number of active memory mappings.
|
||||
const size_t kMaxMappingTableSize = 1000000;
|
||||
|
||||
const size_t kMaxWaitManyNumHandles = kMaxHandleTableSize;
|
||||
|
||||
const size_t kMaxMessageNumBytes = 4 * 1024 * 1024;
|
||||
|
||||
const size_t kMaxMessageNumHandles = 10000;
|
||||
|
||||
// Maximum capacity of a data pipe, in bytes. 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).
|
||||
const size_t kMaxDataPipeCapacityBytes = 256 * 1024 * 1024; // 256 MB.
|
||||
|
||||
const size_t kDefaultDataPipeCapacityBytes = 1024 * 1024; // 1 MB.
|
||||
|
||||
// Alignment for the "start" of the data buffer used by data pipes. (The
|
||||
// alignment of elements will depend on this and the element size.)
|
||||
const size_t kDataPipeBufferAlignmentBytes = 16;
|
||||
|
||||
// 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.)
|
||||
const size_t kMaxSharedMemoryNumBytes = 1024 * 1024 * 1024; // 1 GB.
|
||||
|
||||
} // namespace system
|
||||
} // namespace mojo
|
||||
|
||||
#endif // MOJO_EDK_SYSTEM_CONSTANTS_H_
|
@ -10,7 +10,7 @@
|
||||
#include "base/time/time.h"
|
||||
#include "mojo/edk/embedder/platform_shared_buffer.h"
|
||||
#include "mojo/edk/embedder/platform_support.h"
|
||||
#include "mojo/edk/system/constants.h"
|
||||
#include "mojo/edk/system/configuration.h"
|
||||
#include "mojo/edk/system/data_pipe.h"
|
||||
#include "mojo/edk/system/data_pipe_consumer_dispatcher.h"
|
||||
#include "mojo/edk/system/data_pipe_producer_dispatcher.h"
|
||||
@ -126,11 +126,7 @@ MojoResult Core::Wait(MojoHandle handle,
|
||||
UserPointer<MojoHandleSignalsState> signals_state) {
|
||||
uint32_t unused = static_cast<uint32_t>(-1);
|
||||
HandleSignalsState hss;
|
||||
MojoResult rv = WaitManyInternal(&handle,
|
||||
&signals,
|
||||
1,
|
||||
deadline,
|
||||
&unused,
|
||||
MojoResult rv = WaitManyInternal(&handle, &signals, 1, deadline, &unused,
|
||||
signals_state.IsNull() ? nullptr : &hss);
|
||||
if (rv != MOJO_RESULT_INVALID_ARGUMENT && !signals_state.IsNull())
|
||||
signals_state.Put(hss);
|
||||
@ -145,7 +141,7 @@ MojoResult Core::WaitMany(UserPointer<const MojoHandle> handles,
|
||||
UserPointer<MojoHandleSignalsState> signals_states) {
|
||||
if (num_handles < 1)
|
||||
return MOJO_RESULT_INVALID_ARGUMENT;
|
||||
if (num_handles > kMaxWaitManyNumHandles)
|
||||
if (num_handles > GetConfiguration().max_wait_many_num_handles)
|
||||
return MOJO_RESULT_RESOURCE_EXHAUSTED;
|
||||
|
||||
UserPointer<const MojoHandle>::Reader handles_reader(handles, num_handles);
|
||||
@ -155,23 +151,17 @@ MojoResult Core::WaitMany(UserPointer<const MojoHandle> handles,
|
||||
MojoResult rv;
|
||||
if (signals_states.IsNull()) {
|
||||
rv = WaitManyInternal(handles_reader.GetPointer(),
|
||||
signals_reader.GetPointer(),
|
||||
num_handles,
|
||||
deadline,
|
||||
&index,
|
||||
nullptr);
|
||||
signals_reader.GetPointer(), num_handles, deadline,
|
||||
&index, nullptr);
|
||||
} else {
|
||||
UserPointer<MojoHandleSignalsState>::Writer signals_states_writer(
|
||||
signals_states, num_handles);
|
||||
// Note: The |reinterpret_cast| is safe, since |HandleSignalsState| is a
|
||||
// subclass of |MojoHandleSignalsState| that doesn't add any data members.
|
||||
rv = WaitManyInternal(handles_reader.GetPointer(),
|
||||
signals_reader.GetPointer(),
|
||||
num_handles,
|
||||
deadline,
|
||||
&index,
|
||||
reinterpret_cast<HandleSignalsState*>(
|
||||
signals_states_writer.GetPointer()));
|
||||
signals_reader.GetPointer(), num_handles, deadline,
|
||||
&index, reinterpret_cast<HandleSignalsState*>(
|
||||
signals_states_writer.GetPointer()));
|
||||
if (rv != MOJO_RESULT_INVALID_ARGUMENT)
|
||||
signals_states_writer.Commit();
|
||||
}
|
||||
@ -246,7 +236,7 @@ MojoResult Core::WriteMessage(MojoHandle message_pipe_handle,
|
||||
// validity, even for dispatchers that don't support |WriteMessage()| and will
|
||||
// simply return failure unconditionally. It also breaks the usual
|
||||
// left-to-right verification order of arguments.)
|
||||
if (num_handles > kMaxMessageNumHandles)
|
||||
if (num_handles > GetConfiguration().max_message_num_handles)
|
||||
return MOJO_RESULT_RESOURCE_EXHAUSTED;
|
||||
|
||||
UserPointer<const MojoHandle>::Reader handles_reader(handles, num_handles);
|
||||
@ -263,11 +253,9 @@ MojoResult Core::WriteMessage(MojoHandle message_pipe_handle,
|
||||
// handles from the handle table.
|
||||
{
|
||||
base::AutoLock locker(handle_table_lock_);
|
||||
MojoResult result =
|
||||
handle_table_.MarkBusyAndStartTransport(message_pipe_handle,
|
||||
handles_reader.GetPointer(),
|
||||
num_handles,
|
||||
&transports);
|
||||
MojoResult result = handle_table_.MarkBusyAndStartTransport(
|
||||
message_pipe_handle, handles_reader.GetPointer(), num_handles,
|
||||
&transports);
|
||||
if (result != MOJO_RESULT_OK)
|
||||
return result;
|
||||
}
|
||||
@ -308,12 +296,12 @@ MojoResult Core::ReadMessage(MojoHandle message_pipe_handle,
|
||||
MojoResult rv;
|
||||
if (num_handles_value == 0) {
|
||||
// Easy case: won't receive any handles.
|
||||
rv = dispatcher->ReadMessage(
|
||||
bytes, num_bytes, nullptr, &num_handles_value, flags);
|
||||
rv = dispatcher->ReadMessage(bytes, num_bytes, nullptr, &num_handles_value,
|
||||
flags);
|
||||
} else {
|
||||
DispatcherVector dispatchers;
|
||||
rv = dispatcher->ReadMessage(
|
||||
bytes, num_bytes, &dispatchers, &num_handles_value, flags);
|
||||
rv = dispatcher->ReadMessage(bytes, num_bytes, &dispatchers,
|
||||
&num_handles_value, flags);
|
||||
if (!dispatchers.empty()) {
|
||||
DCHECK_EQ(rv, MOJO_RESULT_OK);
|
||||
DCHECK(!num_handles.IsNull());
|
||||
@ -466,8 +454,8 @@ MojoResult Core::CreateSharedBuffer(
|
||||
return result;
|
||||
|
||||
scoped_refptr<SharedBufferDispatcher> dispatcher;
|
||||
result = SharedBufferDispatcher::Create(
|
||||
platform_support(), validated_options, num_bytes, &dispatcher);
|
||||
result = SharedBufferDispatcher::Create(platform_support(), validated_options,
|
||||
num_bytes, &dispatcher);
|
||||
if (result != MOJO_RESULT_OK) {
|
||||
DCHECK(!dispatcher.get());
|
||||
return result;
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include "base/logging.h"
|
||||
#include "base/memory/ref_counted.h"
|
||||
#include "mojo/edk/embedder/simple_platform_support.h"
|
||||
#include "mojo/edk/system/constants.h"
|
||||
#include "mojo/edk/system/configuration.h"
|
||||
#include "mojo/edk/system/core.h"
|
||||
#include "mojo/edk/system/dispatcher.h"
|
||||
#include "mojo/edk/system/memory.h"
|
||||
@ -50,7 +50,7 @@ class MockDispatcher : public Dispatcher {
|
||||
info_->IncrementWriteMessageCallCount();
|
||||
lock().AssertAcquired();
|
||||
|
||||
if (num_bytes > kMaxMessageNumBytes)
|
||||
if (num_bytes > GetConfiguration().max_message_num_bytes)
|
||||
return MOJO_RESULT_RESOURCE_EXHAUSTED;
|
||||
|
||||
if (transports)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -10,7 +10,7 @@
|
||||
#include <limits>
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "mojo/edk/system/constants.h"
|
||||
#include "mojo/edk/system/configuration.h"
|
||||
#include "mojo/edk/system/memory.h"
|
||||
#include "mojo/edk/system/options_validation.h"
|
||||
#include "mojo/edk/system/waiter_list.h"
|
||||
@ -19,11 +19,15 @@ namespace mojo {
|
||||
namespace system {
|
||||
|
||||
// static
|
||||
const MojoCreateDataPipeOptions DataPipe::kDefaultCreateOptions = {
|
||||
static_cast<uint32_t>(sizeof(MojoCreateDataPipeOptions)),
|
||||
MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE,
|
||||
1u,
|
||||
static_cast<uint32_t>(kDefaultDataPipeCapacityBytes)};
|
||||
MojoCreateDataPipeOptions DataPipe::GetDefaultCreateOptions() {
|
||||
MojoCreateDataPipeOptions result = {
|
||||
static_cast<uint32_t>(sizeof(MojoCreateDataPipeOptions)),
|
||||
MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE,
|
||||
1u,
|
||||
static_cast<uint32_t>(
|
||||
GetConfiguration().default_data_pipe_capacity_bytes)};
|
||||
return result;
|
||||
}
|
||||
|
||||
// static
|
||||
MojoResult DataPipe::ValidateCreateOptions(
|
||||
@ -32,7 +36,7 @@ MojoResult DataPipe::ValidateCreateOptions(
|
||||
const MojoCreateDataPipeOptionsFlags kKnownFlags =
|
||||
MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_MAY_DISCARD;
|
||||
|
||||
*out_options = kDefaultCreateOptions;
|
||||
*out_options = GetDefaultCreateOptions();
|
||||
if (in_options.IsNull())
|
||||
return MOJO_RESULT_OK;
|
||||
|
||||
@ -48,28 +52,31 @@ MojoResult DataPipe::ValidateCreateOptions(
|
||||
|
||||
// Checks for fields beyond |flags|:
|
||||
|
||||
if (!OPTIONS_STRUCT_HAS_MEMBER(
|
||||
MojoCreateDataPipeOptions, element_num_bytes, reader))
|
||||
if (!OPTIONS_STRUCT_HAS_MEMBER(MojoCreateDataPipeOptions, element_num_bytes,
|
||||
reader))
|
||||
return MOJO_RESULT_OK;
|
||||
if (reader.options().element_num_bytes == 0)
|
||||
return MOJO_RESULT_INVALID_ARGUMENT;
|
||||
out_options->element_num_bytes = reader.options().element_num_bytes;
|
||||
|
||||
if (!OPTIONS_STRUCT_HAS_MEMBER(
|
||||
MojoCreateDataPipeOptions, capacity_num_bytes, reader) ||
|
||||
if (!OPTIONS_STRUCT_HAS_MEMBER(MojoCreateDataPipeOptions, capacity_num_bytes,
|
||||
reader) ||
|
||||
reader.options().capacity_num_bytes == 0) {
|
||||
// Round the default capacity down to a multiple of the element size (but at
|
||||
// least one element).
|
||||
size_t default_data_pipe_capacity_bytes =
|
||||
GetConfiguration().default_data_pipe_capacity_bytes;
|
||||
out_options->capacity_num_bytes =
|
||||
std::max(static_cast<uint32_t>(kDefaultDataPipeCapacityBytes -
|
||||
(kDefaultDataPipeCapacityBytes %
|
||||
std::max(static_cast<uint32_t>(default_data_pipe_capacity_bytes -
|
||||
(default_data_pipe_capacity_bytes %
|
||||
out_options->element_num_bytes)),
|
||||
out_options->element_num_bytes);
|
||||
return MOJO_RESULT_OK;
|
||||
}
|
||||
if (reader.options().capacity_num_bytes % out_options->element_num_bytes != 0)
|
||||
return MOJO_RESULT_INVALID_ARGUMENT;
|
||||
if (reader.options().capacity_num_bytes > kMaxDataPipeCapacityBytes)
|
||||
if (reader.options().capacity_num_bytes >
|
||||
GetConfiguration().max_data_pipe_capacity_bytes)
|
||||
return MOJO_RESULT_RESOURCE_EXHAUSTED;
|
||||
out_options->capacity_num_bytes = reader.options().capacity_num_bytes;
|
||||
|
||||
@ -148,8 +155,8 @@ MojoResult DataPipe::ProducerBeginWriteData(
|
||||
return MOJO_RESULT_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
MojoResult rv = ProducerBeginWriteDataImplNoLock(
|
||||
buffer, buffer_num_bytes, min_num_bytes_to_write);
|
||||
MojoResult rv = ProducerBeginWriteDataImplNoLock(buffer, buffer_num_bytes,
|
||||
min_num_bytes_to_write);
|
||||
if (rv != MOJO_RESULT_OK)
|
||||
return rv;
|
||||
// Note: No need to awake producer waiters, even though we're going from
|
||||
@ -345,8 +352,8 @@ MojoResult DataPipe::ConsumerBeginReadData(
|
||||
return MOJO_RESULT_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
MojoResult rv = ConsumerBeginReadDataImplNoLock(
|
||||
buffer, buffer_num_bytes, min_num_bytes_to_read);
|
||||
MojoResult rv = ConsumerBeginReadDataImplNoLock(buffer, buffer_num_bytes,
|
||||
min_num_bytes_to_read);
|
||||
if (rv != MOJO_RESULT_OK)
|
||||
return rv;
|
||||
DCHECK(consumer_in_two_phase_read_no_lock());
|
||||
|
@ -35,7 +35,7 @@ class MOJO_SYSTEM_IMPL_EXPORT DataPipe
|
||||
// The default options for |MojoCreateDataPipe()|. (Real uses should obtain
|
||||
// this via |ValidateCreateOptions()| with a null |in_options|; this is
|
||||
// exposed directly for testing convenience.)
|
||||
static const MojoCreateDataPipeOptions kDefaultCreateOptions;
|
||||
static MojoCreateDataPipeOptions GetDefaultCreateOptions();
|
||||
|
||||
// Validates and/or sets default options for |MojoCreateDataPipeOptions|. If
|
||||
// non-null, |in_options| must point to a struct of at least
|
||||
@ -117,12 +117,11 @@ class MOJO_SYSTEM_IMPL_EXPORT DataPipe
|
||||
|
||||
virtual void ConsumerCloseImplNoLock() = 0;
|
||||
// |*num_bytes| will be a nonzero multiple of |element_num_bytes_|.
|
||||
virtual MojoResult ConsumerReadDataImplNoLock(
|
||||
UserPointer<void> elements,
|
||||
UserPointer<uint32_t> num_bytes,
|
||||
uint32_t max_num_bytes_to_read,
|
||||
uint32_t min_num_bytes_to_read,
|
||||
bool peek) = 0;
|
||||
virtual MojoResult ConsumerReadDataImplNoLock(UserPointer<void> elements,
|
||||
UserPointer<uint32_t> num_bytes,
|
||||
uint32_t max_num_bytes_to_read,
|
||||
uint32_t min_num_bytes_to_read,
|
||||
bool peek) = 0;
|
||||
virtual MojoResult ConsumerDiscardDataImplNoLock(
|
||||
UserPointer<uint32_t> num_bytes,
|
||||
uint32_t max_num_bytes_to_discard,
|
||||
|
@ -77,9 +77,7 @@ MojoResult DataPipeConsumerDispatcher::ReadDataImplNoLock(
|
||||
}
|
||||
|
||||
return data_pipe_->ConsumerReadData(
|
||||
elements,
|
||||
num_bytes,
|
||||
!!(flags & MOJO_READ_DATA_FLAG_ALL_OR_NONE),
|
||||
elements, num_bytes, !!(flags & MOJO_READ_DATA_FLAG_ALL_OR_NONE),
|
||||
!!(flags & MOJO_READ_DATA_FLAG_PEEK));
|
||||
}
|
||||
|
||||
@ -91,8 +89,7 @@ MojoResult DataPipeConsumerDispatcher::BeginReadDataImplNoLock(
|
||||
|
||||
// These flags may not be used in two-phase mode.
|
||||
if ((flags & MOJO_READ_DATA_FLAG_DISCARD) ||
|
||||
(flags & MOJO_READ_DATA_FLAG_QUERY) ||
|
||||
(flags & MOJO_READ_DATA_FLAG_PEEK))
|
||||
(flags & MOJO_READ_DATA_FLAG_QUERY) || (flags & MOJO_READ_DATA_FLAG_PEEK))
|
||||
return MOJO_RESULT_INVALID_ARGUMENT;
|
||||
|
||||
return data_pipe_->ConsumerBeginReadData(
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
#include <limits>
|
||||
|
||||
#include "mojo/edk/system/constants.h"
|
||||
#include "mojo/edk/system/configuration.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
namespace mojo {
|
||||
@ -28,9 +28,8 @@ void RevalidateCreateOptions(
|
||||
// Nothing to check for flags.
|
||||
EXPECT_GT(validated_options.element_num_bytes, 0u);
|
||||
EXPECT_GT(validated_options.capacity_num_bytes, 0u);
|
||||
EXPECT_EQ(0u,
|
||||
validated_options.capacity_num_bytes %
|
||||
validated_options.element_num_bytes);
|
||||
EXPECT_EQ(0u, validated_options.capacity_num_bytes %
|
||||
validated_options.element_num_bytes);
|
||||
|
||||
MojoCreateDataPipeOptions revalidated_options = {};
|
||||
EXPECT_EQ(MOJO_RESULT_OK,
|
||||
@ -48,10 +47,10 @@ void RevalidateCreateOptions(
|
||||
// checks done by |RevalidateCreateOptions()|.)
|
||||
void CheckDefaultCapacity(const MojoCreateDataPipeOptions& validated_options) {
|
||||
EXPECT_LE(validated_options.capacity_num_bytes,
|
||||
kDefaultDataPipeCapacityBytes);
|
||||
GetConfiguration().default_data_pipe_capacity_bytes);
|
||||
EXPECT_GT(validated_options.capacity_num_bytes +
|
||||
validated_options.element_num_bytes,
|
||||
kDefaultDataPipeCapacityBytes);
|
||||
GetConfiguration().default_data_pipe_capacity_bytes);
|
||||
}
|
||||
|
||||
// Tests valid inputs to |ValidateCreateOptions()|.
|
||||
@ -59,9 +58,8 @@ TEST(DataPipeTest, ValidateCreateOptionsValid) {
|
||||
// Default options.
|
||||
{
|
||||
MojoCreateDataPipeOptions validated_options = {};
|
||||
EXPECT_EQ(
|
||||
MOJO_RESULT_OK,
|
||||
DataPipe::ValidateCreateOptions(NullUserPointer(), &validated_options));
|
||||
EXPECT_EQ(MOJO_RESULT_OK, DataPipe::ValidateCreateOptions(
|
||||
NullUserPointer(), &validated_options));
|
||||
RevalidateCreateOptions(validated_options);
|
||||
CheckDefaultCapacity(validated_options);
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include "mojo/edk/system/dispatcher.h"
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "mojo/edk/system/constants.h"
|
||||
#include "mojo/edk/system/configuration.h"
|
||||
#include "mojo/edk/system/message_pipe_dispatcher.h"
|
||||
#include "mojo/edk/system/platform_handle_dispatcher.h"
|
||||
#include "mojo/edk/system/shared_buffer_dispatcher.h"
|
||||
@ -58,8 +58,8 @@ bool Dispatcher::TransportDataAccess::EndSerializeAndClose(
|
||||
size_t* actual_size,
|
||||
embedder::PlatformHandleVector* platform_handles) {
|
||||
DCHECK(dispatcher);
|
||||
return dispatcher->EndSerializeAndClose(
|
||||
channel, destination, actual_size, platform_handles);
|
||||
return dispatcher->EndSerializeAndClose(channel, destination, actual_size,
|
||||
platform_handles);
|
||||
}
|
||||
|
||||
// static
|
||||
@ -72,7 +72,7 @@ scoped_refptr<Dispatcher> Dispatcher::TransportDataAccess::Deserialize(
|
||||
switch (static_cast<int32_t>(type)) {
|
||||
case kTypeUnknown:
|
||||
DVLOG(2) << "Deserializing invalid handle";
|
||||
return scoped_refptr<Dispatcher>();
|
||||
return nullptr;
|
||||
case kTypeMessagePipe:
|
||||
return scoped_refptr<Dispatcher>(
|
||||
MessagePipeDispatcher::Deserialize(channel, source, size));
|
||||
@ -81,7 +81,7 @@ scoped_refptr<Dispatcher> Dispatcher::TransportDataAccess::Deserialize(
|
||||
// TODO(vtl): Implement.
|
||||
LOG(WARNING) << "Deserialization of dispatcher type " << type
|
||||
<< " not supported";
|
||||
return scoped_refptr<Dispatcher>();
|
||||
return nullptr;
|
||||
case kTypeSharedBuffer:
|
||||
return scoped_refptr<Dispatcher>(SharedBufferDispatcher::Deserialize(
|
||||
channel, source, size, platform_handles));
|
||||
@ -90,7 +90,7 @@ scoped_refptr<Dispatcher> Dispatcher::TransportDataAccess::Deserialize(
|
||||
channel, source, size, platform_handles));
|
||||
}
|
||||
LOG(WARNING) << "Unknown dispatcher type " << type;
|
||||
return scoped_refptr<Dispatcher>();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MojoResult Dispatcher::Close() {
|
||||
@ -107,8 +107,9 @@ MojoResult Dispatcher::WriteMessage(
|
||||
uint32_t num_bytes,
|
||||
std::vector<DispatcherTransport>* transports,
|
||||
MojoWriteMessageFlags flags) {
|
||||
DCHECK(!transports || (transports->size() > 0 &&
|
||||
transports->size() < kMaxMessageNumHandles));
|
||||
DCHECK(!transports ||
|
||||
(transports->size() > 0 &&
|
||||
transports->size() < GetConfiguration().max_message_num_handles));
|
||||
|
||||
base::AutoLock locker(lock_);
|
||||
if (is_closed_)
|
||||
@ -129,8 +130,8 @@ MojoResult Dispatcher::ReadMessage(UserPointer<void> bytes,
|
||||
if (is_closed_)
|
||||
return MOJO_RESULT_INVALID_ARGUMENT;
|
||||
|
||||
return ReadMessageImplNoLock(
|
||||
bytes, num_bytes, dispatchers, num_dispatchers, flags);
|
||||
return ReadMessageImplNoLock(bytes, num_bytes, dispatchers, num_dispatchers,
|
||||
flags);
|
||||
}
|
||||
|
||||
MojoResult Dispatcher::WriteData(UserPointer<const void> elements,
|
||||
@ -473,8 +474,8 @@ bool Dispatcher::EndSerializeAndClose(
|
||||
base::AutoLock locker(lock_);
|
||||
#endif
|
||||
|
||||
return EndSerializeAndCloseImplNoLock(
|
||||
channel, destination, actual_size, platform_handles);
|
||||
return EndSerializeAndCloseImplNoLock(channel, destination, actual_size,
|
||||
platform_handles);
|
||||
}
|
||||
|
||||
// DispatcherTransport ---------------------------------------------------------
|
||||
|
@ -14,7 +14,6 @@
|
||||
#include "base/memory/ref_counted.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "base/synchronization/lock.h"
|
||||
#include "mojo/edk/embedder/platform_handle.h"
|
||||
#include "mojo/edk/embedder/platform_handle_vector.h"
|
||||
#include "mojo/edk/system/handle_signals_state.h"
|
||||
#include "mojo/edk/system/memory.h"
|
||||
@ -48,7 +47,7 @@ namespace test {
|
||||
|
||||
// Test helper. We need to declare it here so we can friend it.
|
||||
MOJO_SYSTEM_IMPL_EXPORT DispatcherTransport
|
||||
DispatcherTryStartTransport(Dispatcher* dispatcher);
|
||||
DispatcherTryStartTransport(Dispatcher* dispatcher);
|
||||
|
||||
} // namespace test
|
||||
|
||||
|
@ -44,31 +44,24 @@ TEST(DispatcherTest, Basic) {
|
||||
EXPECT_EQ(Dispatcher::kTypeUnknown, d->GetType());
|
||||
|
||||
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
|
||||
d->WriteMessage(
|
||||
NullUserPointer(), 0, nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE));
|
||||
d->WriteMessage(NullUserPointer(), 0, nullptr,
|
||||
MOJO_WRITE_MESSAGE_FLAG_NONE));
|
||||
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
|
||||
d->ReadMessage(NullUserPointer(),
|
||||
NullUserPointer(),
|
||||
nullptr,
|
||||
nullptr,
|
||||
MOJO_WRITE_MESSAGE_FLAG_NONE));
|
||||
EXPECT_EQ(
|
||||
MOJO_RESULT_INVALID_ARGUMENT,
|
||||
d->WriteData(
|
||||
NullUserPointer(), NullUserPointer(), MOJO_WRITE_DATA_FLAG_NONE));
|
||||
EXPECT_EQ(
|
||||
MOJO_RESULT_INVALID_ARGUMENT,
|
||||
d->BeginWriteData(
|
||||
NullUserPointer(), NullUserPointer(), MOJO_WRITE_DATA_FLAG_NONE));
|
||||
d->ReadMessage(NullUserPointer(), NullUserPointer(), nullptr,
|
||||
nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE));
|
||||
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
|
||||
d->WriteData(NullUserPointer(), NullUserPointer(),
|
||||
MOJO_WRITE_DATA_FLAG_NONE));
|
||||
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
|
||||
d->BeginWriteData(NullUserPointer(), NullUserPointer(),
|
||||
MOJO_WRITE_DATA_FLAG_NONE));
|
||||
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, d->EndWriteData(0));
|
||||
EXPECT_EQ(
|
||||
MOJO_RESULT_INVALID_ARGUMENT,
|
||||
d->ReadData(
|
||||
NullUserPointer(), NullUserPointer(), MOJO_READ_DATA_FLAG_NONE));
|
||||
EXPECT_EQ(
|
||||
MOJO_RESULT_INVALID_ARGUMENT,
|
||||
d->BeginReadData(
|
||||
NullUserPointer(), NullUserPointer(), MOJO_READ_DATA_FLAG_NONE));
|
||||
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
|
||||
d->ReadData(NullUserPointer(), NullUserPointer(),
|
||||
MOJO_READ_DATA_FLAG_NONE));
|
||||
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
|
||||
d->BeginReadData(NullUserPointer(), NullUserPointer(),
|
||||
MOJO_READ_DATA_FLAG_NONE));
|
||||
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, d->EndReadData(0));
|
||||
Waiter w;
|
||||
w.Init();
|
||||
@ -90,31 +83,24 @@ TEST(DispatcherTest, Basic) {
|
||||
EXPECT_EQ(MOJO_RESULT_OK, d->Close());
|
||||
|
||||
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
|
||||
d->WriteMessage(
|
||||
NullUserPointer(), 0, nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE));
|
||||
d->WriteMessage(NullUserPointer(), 0, nullptr,
|
||||
MOJO_WRITE_MESSAGE_FLAG_NONE));
|
||||
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
|
||||
d->ReadMessage(NullUserPointer(),
|
||||
NullUserPointer(),
|
||||
nullptr,
|
||||
nullptr,
|
||||
MOJO_WRITE_MESSAGE_FLAG_NONE));
|
||||
EXPECT_EQ(
|
||||
MOJO_RESULT_INVALID_ARGUMENT,
|
||||
d->WriteData(
|
||||
NullUserPointer(), NullUserPointer(), MOJO_WRITE_DATA_FLAG_NONE));
|
||||
EXPECT_EQ(
|
||||
MOJO_RESULT_INVALID_ARGUMENT,
|
||||
d->BeginWriteData(
|
||||
NullUserPointer(), NullUserPointer(), MOJO_WRITE_DATA_FLAG_NONE));
|
||||
d->ReadMessage(NullUserPointer(), NullUserPointer(), nullptr,
|
||||
nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE));
|
||||
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
|
||||
d->WriteData(NullUserPointer(), NullUserPointer(),
|
||||
MOJO_WRITE_DATA_FLAG_NONE));
|
||||
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
|
||||
d->BeginWriteData(NullUserPointer(), NullUserPointer(),
|
||||
MOJO_WRITE_DATA_FLAG_NONE));
|
||||
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, d->EndWriteData(0));
|
||||
EXPECT_EQ(
|
||||
MOJO_RESULT_INVALID_ARGUMENT,
|
||||
d->ReadData(
|
||||
NullUserPointer(), NullUserPointer(), MOJO_READ_DATA_FLAG_NONE));
|
||||
EXPECT_EQ(
|
||||
MOJO_RESULT_INVALID_ARGUMENT,
|
||||
d->BeginReadData(
|
||||
NullUserPointer(), NullUserPointer(), MOJO_READ_DATA_FLAG_NONE));
|
||||
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
|
||||
d->ReadData(NullUserPointer(), NullUserPointer(),
|
||||
MOJO_READ_DATA_FLAG_NONE));
|
||||
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
|
||||
d->BeginReadData(NullUserPointer(), NullUserPointer(),
|
||||
MOJO_READ_DATA_FLAG_NONE));
|
||||
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, d->EndReadData(0));
|
||||
hss = HandleSignalsState();
|
||||
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
|
||||
@ -172,45 +158,40 @@ class ThreadSafetyStressThread : public base::SimpleThread {
|
||||
break;
|
||||
}
|
||||
case WRITE_MESSAGE:
|
||||
EXPECT_EQ(
|
||||
MOJO_RESULT_INVALID_ARGUMENT,
|
||||
dispatcher_->WriteMessage(
|
||||
NullUserPointer(), 0, nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE));
|
||||
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
|
||||
dispatcher_->WriteMessage(NullUserPointer(), 0, nullptr,
|
||||
MOJO_WRITE_MESSAGE_FLAG_NONE));
|
||||
break;
|
||||
case READ_MESSAGE:
|
||||
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
|
||||
dispatcher_->ReadMessage(NullUserPointer(),
|
||||
NullUserPointer(),
|
||||
nullptr,
|
||||
nullptr,
|
||||
dispatcher_->ReadMessage(NullUserPointer(), NullUserPointer(),
|
||||
nullptr, nullptr,
|
||||
MOJO_WRITE_MESSAGE_FLAG_NONE));
|
||||
break;
|
||||
case WRITE_DATA:
|
||||
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
|
||||
dispatcher_->WriteData(NullUserPointer(),
|
||||
NullUserPointer(),
|
||||
dispatcher_->WriteData(NullUserPointer(), NullUserPointer(),
|
||||
MOJO_WRITE_DATA_FLAG_NONE));
|
||||
break;
|
||||
case BEGIN_WRITE_DATA:
|
||||
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
|
||||
dispatcher_->BeginWriteData(NullUserPointer(),
|
||||
NullUserPointer(),
|
||||
MOJO_WRITE_DATA_FLAG_NONE));
|
||||
EXPECT_EQ(
|
||||
MOJO_RESULT_INVALID_ARGUMENT,
|
||||
dispatcher_->BeginWriteData(NullUserPointer(), NullUserPointer(),
|
||||
MOJO_WRITE_DATA_FLAG_NONE));
|
||||
break;
|
||||
case END_WRITE_DATA:
|
||||
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, dispatcher_->EndWriteData(0));
|
||||
break;
|
||||
case READ_DATA:
|
||||
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
|
||||
dispatcher_->ReadData(NullUserPointer(),
|
||||
NullUserPointer(),
|
||||
dispatcher_->ReadData(NullUserPointer(), NullUserPointer(),
|
||||
MOJO_READ_DATA_FLAG_NONE));
|
||||
break;
|
||||
case BEGIN_READ_DATA:
|
||||
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
|
||||
dispatcher_->BeginReadData(NullUserPointer(),
|
||||
NullUserPointer(),
|
||||
MOJO_READ_DATA_FLAG_NONE));
|
||||
EXPECT_EQ(
|
||||
MOJO_RESULT_INVALID_ARGUMENT,
|
||||
dispatcher_->BeginReadData(NullUserPointer(), NullUserPointer(),
|
||||
MOJO_READ_DATA_FLAG_NONE));
|
||||
break;
|
||||
case END_READ_DATA:
|
||||
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, dispatcher_->EndReadData(0));
|
||||
|
@ -1,24 +0,0 @@
|
||||
// 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_SYSTEM_ENTRYPOINTS_H_
|
||||
#define MOJO_EDK_SYSTEM_ENTRYPOINTS_H_
|
||||
|
||||
namespace mojo {
|
||||
namespace system {
|
||||
|
||||
class Core;
|
||||
|
||||
namespace entrypoints {
|
||||
|
||||
// Sets the instance of Core to be used by system functions.
|
||||
void SetCore(Core* core);
|
||||
// Gets the instance of Core to be used by system functions.
|
||||
Core* GetCore();
|
||||
|
||||
} // namespace entrypoints
|
||||
} // namepace system
|
||||
} // namespace mojo
|
||||
|
||||
#endif // MOJO_EDK_SYSTEM_ENTRYPOINTS_H_
|
@ -4,9 +4,10 @@
|
||||
|
||||
#include "mojo/edk/system/handle_table.h"
|
||||
|
||||
#include <limits>
|
||||
#include "base/logging.h"
|
||||
#include "base/macros.h"
|
||||
#include "mojo/edk/system/constants.h"
|
||||
#include "mojo/edk/system/configuration.h"
|
||||
#include "mojo/edk/system/dispatcher.h"
|
||||
|
||||
namespace mojo {
|
||||
@ -59,7 +60,7 @@ MojoResult HandleTable::GetAndRemoveDispatcher(
|
||||
|
||||
MojoHandle HandleTable::AddDispatcher(
|
||||
const scoped_refptr<Dispatcher>& dispatcher) {
|
||||
if (handle_to_entry_map_.size() >= kMaxHandleTableSize)
|
||||
if (handle_to_entry_map_.size() >= GetConfiguration().max_handle_table_size)
|
||||
return MOJO_HANDLE_INVALID;
|
||||
return AddDispatcherNoSizeCheck(dispatcher);
|
||||
}
|
||||
@ -67,7 +68,8 @@ MojoHandle HandleTable::AddDispatcher(
|
||||
std::pair<MojoHandle, MojoHandle> HandleTable::AddDispatcherPair(
|
||||
const scoped_refptr<Dispatcher>& dispatcher0,
|
||||
const scoped_refptr<Dispatcher>& dispatcher1) {
|
||||
if (handle_to_entry_map_.size() + 1 >= kMaxHandleTableSize)
|
||||
if (handle_to_entry_map_.size() + 1 >=
|
||||
GetConfiguration().max_handle_table_size)
|
||||
return std::make_pair(MOJO_HANDLE_INVALID, MOJO_HANDLE_INVALID);
|
||||
return std::make_pair(AddDispatcherNoSizeCheck(dispatcher0),
|
||||
AddDispatcherNoSizeCheck(dispatcher1));
|
||||
@ -75,17 +77,17 @@ std::pair<MojoHandle, MojoHandle> HandleTable::AddDispatcherPair(
|
||||
|
||||
bool HandleTable::AddDispatcherVector(const DispatcherVector& dispatchers,
|
||||
MojoHandle* handles) {
|
||||
DCHECK_LE(dispatchers.size(), kMaxMessageNumHandles);
|
||||
DCHECK(handles);
|
||||
// TODO(vtl): |std::numeric_limits<size_t>::max()| isn't a compile-time
|
||||
// expression in C++03.
|
||||
static_assert(
|
||||
static_cast<uint64_t>(kMaxHandleTableSize) + kMaxMessageNumHandles <
|
||||
(sizeof(size_t) == 8 ? kuint64max
|
||||
: static_cast<uint64_t>(kuint32max)),
|
||||
"Addition may overflow");
|
||||
size_t max_message_num_handles = GetConfiguration().max_message_num_handles;
|
||||
size_t max_handle_table_size = GetConfiguration().max_handle_table_size;
|
||||
|
||||
if (handle_to_entry_map_.size() + dispatchers.size() > kMaxHandleTableSize)
|
||||
DCHECK_LE(dispatchers.size(), max_message_num_handles);
|
||||
DCHECK(handles);
|
||||
DCHECK_LT(
|
||||
static_cast<uint64_t>(max_handle_table_size) + max_message_num_handles,
|
||||
std::numeric_limits<size_t>::max())
|
||||
<< "Addition may overflow";
|
||||
|
||||
if (handle_to_entry_map_.size() + dispatchers.size() > max_handle_table_size)
|
||||
return false;
|
||||
|
||||
for (size_t i = 0; i < dispatchers.size(); i++) {
|
||||
@ -106,7 +108,7 @@ MojoResult HandleTable::MarkBusyAndStartTransport(
|
||||
std::vector<DispatcherTransport>* transports) {
|
||||
DCHECK_NE(disallowed_handle, MOJO_HANDLE_INVALID);
|
||||
DCHECK(handles);
|
||||
DCHECK_LE(num_handles, kMaxMessageNumHandles);
|
||||
DCHECK_LE(num_handles, GetConfiguration().max_message_num_handles);
|
||||
DCHECK(transports);
|
||||
DCHECK_EQ(transports->size(), num_handles);
|
||||
|
||||
@ -187,7 +189,8 @@ MojoResult HandleTable::MarkBusyAndStartTransport(
|
||||
MojoHandle HandleTable::AddDispatcherNoSizeCheck(
|
||||
const scoped_refptr<Dispatcher>& dispatcher) {
|
||||
DCHECK(dispatcher.get());
|
||||
DCHECK_LT(handle_to_entry_map_.size(), kMaxHandleTableSize);
|
||||
DCHECK_LT(handle_to_entry_map_.size(),
|
||||
GetConfiguration().max_handle_table_size);
|
||||
DCHECK_NE(next_handle_, MOJO_HANDLE_INVALID);
|
||||
|
||||
// TODO(vtl): Maybe we want to do something different/smarter. (Or maybe try
|
||||
@ -212,7 +215,7 @@ MojoHandle HandleTable::AddDispatcherNoSizeCheck(
|
||||
void HandleTable::RemoveBusyHandles(const MojoHandle* handles,
|
||||
uint32_t num_handles) {
|
||||
DCHECK(handles);
|
||||
DCHECK_LE(num_handles, kMaxMessageNumHandles);
|
||||
DCHECK_LE(num_handles, GetConfiguration().max_message_num_handles);
|
||||
|
||||
for (uint32_t i = 0; i < num_handles; i++) {
|
||||
HandleToEntryMap::iterator it = handle_to_entry_map_.find(handles[i]);
|
||||
@ -226,7 +229,7 @@ void HandleTable::RemoveBusyHandles(const MojoHandle* handles,
|
||||
void HandleTable::RestoreBusyHandles(const MojoHandle* handles,
|
||||
uint32_t num_handles) {
|
||||
DCHECK(handles);
|
||||
DCHECK_LE(num_handles, kMaxMessageNumHandles);
|
||||
DCHECK_LE(num_handles, GetConfiguration().max_message_num_handles);
|
||||
|
||||
for (uint32_t i = 0; i < num_handles; i++) {
|
||||
HandleToEntryMap::iterator it = handle_to_entry_map_.find(handles[i]);
|
||||
|
@ -15,7 +15,7 @@
|
||||
#include <algorithm>
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "mojo/edk/system/constants.h"
|
||||
#include "mojo/edk/system/configuration.h"
|
||||
|
||||
namespace mojo {
|
||||
namespace system {
|
||||
@ -301,7 +301,8 @@ void LocalDataPipe::EnsureBufferNoLock() {
|
||||
if (buffer_)
|
||||
return;
|
||||
buffer_.reset(static_cast<char*>(
|
||||
base::AlignedAlloc(capacity_num_bytes(), kDataPipeBufferAlignmentBytes)));
|
||||
base::AlignedAlloc(capacity_num_bytes(),
|
||||
GetConfiguration().data_pipe_buffer_alignment_bytes)));
|
||||
}
|
||||
|
||||
void LocalDataPipe::DestroyBufferNoLock() {
|
||||
|
@ -44,12 +44,11 @@ class MOJO_SYSTEM_IMPL_EXPORT LocalDataPipe : public DataPipe {
|
||||
uint32_t num_bytes_written) override;
|
||||
HandleSignalsState ProducerGetHandleSignalsStateImplNoLock() const override;
|
||||
void ConsumerCloseImplNoLock() override;
|
||||
MojoResult ConsumerReadDataImplNoLock(
|
||||
UserPointer<void> elements,
|
||||
UserPointer<uint32_t> num_bytes,
|
||||
uint32_t max_num_bytes_to_read,
|
||||
uint32_t min_num_bytes_to_read,
|
||||
bool peek) override;
|
||||
MojoResult ConsumerReadDataImplNoLock(UserPointer<void> elements,
|
||||
UserPointer<uint32_t> num_bytes,
|
||||
uint32_t max_num_bytes_to_read,
|
||||
uint32_t min_num_bytes_to_read,
|
||||
bool peek) override;
|
||||
MojoResult ConsumerDiscardDataImplNoLock(
|
||||
UserPointer<uint32_t> num_bytes,
|
||||
uint32_t max_num_bytes_to_discard,
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -6,7 +6,7 @@
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "mojo/edk/embedder/platform_shared_buffer.h"
|
||||
#include "mojo/edk/system/constants.h"
|
||||
#include "mojo/edk/system/configuration.h"
|
||||
|
||||
namespace mojo {
|
||||
namespace system {
|
||||
@ -23,7 +23,8 @@ MojoResult MappingTable::AddMapping(
|
||||
scoped_ptr<embedder::PlatformSharedBufferMapping> mapping) {
|
||||
DCHECK(mapping);
|
||||
|
||||
if (address_to_mapping_map_.size() >= kMaxMappingTableSize)
|
||||
if (address_to_mapping_map_.size() >=
|
||||
GetConfiguration().max_mapping_table_sze)
|
||||
return MOJO_RESULT_RESOURCE_EXHAUSTED;
|
||||
|
||||
uintptr_t address = reinterpret_cast<uintptr_t>(mapping->GetBase());
|
||||
|
@ -40,20 +40,20 @@ template void MOJO_SYSTEM_IMPL_EXPORT CheckUserPointer<8, 8>(const void*);
|
||||
|
||||
template <size_t size, size_t alignment>
|
||||
void MOJO_SYSTEM_IMPL_EXPORT
|
||||
CheckUserPointerWithCount(const void* pointer, size_t count) {
|
||||
CheckUserPointerWithCount(const void* pointer, size_t count) {
|
||||
CHECK_LE(count, std::numeric_limits<size_t>::max() / size);
|
||||
CHECK(count == 0 || (pointer && IsAligned<alignment>(pointer)));
|
||||
}
|
||||
|
||||
// Explicitly instantiate the sizes we need. Add instantiations as needed.
|
||||
template void MOJO_SYSTEM_IMPL_EXPORT
|
||||
CheckUserPointerWithCount<1, 1>(const void*, size_t);
|
||||
CheckUserPointerWithCount<1, 1>(const void*, size_t);
|
||||
template void MOJO_SYSTEM_IMPL_EXPORT
|
||||
CheckUserPointerWithCount<4, 4>(const void*, size_t);
|
||||
CheckUserPointerWithCount<4, 4>(const void*, size_t);
|
||||
template void MOJO_SYSTEM_IMPL_EXPORT
|
||||
CheckUserPointerWithCount<8, 4>(const void*, size_t);
|
||||
CheckUserPointerWithCount<8, 4>(const void*, size_t);
|
||||
template void MOJO_SYSTEM_IMPL_EXPORT
|
||||
CheckUserPointerWithCount<8, 8>(const void*, size_t);
|
||||
CheckUserPointerWithCount<8, 8>(const void*, size_t);
|
||||
|
||||
template <size_t alignment>
|
||||
void CheckUserPointerWithSize(const void* pointer, size_t size) {
|
||||
@ -65,9 +65,9 @@ void CheckUserPointerWithSize(const void* pointer, size_t size) {
|
||||
|
||||
// Explicitly instantiate the sizes we need. Add instantiations as needed.
|
||||
template void MOJO_SYSTEM_IMPL_EXPORT
|
||||
CheckUserPointerWithSize<1>(const void*, size_t);
|
||||
CheckUserPointerWithSize<1>(const void*, size_t);
|
||||
template void MOJO_SYSTEM_IMPL_EXPORT
|
||||
CheckUserPointerWithSize<4>(const void*, size_t);
|
||||
CheckUserPointerWithSize<4>(const void*, size_t);
|
||||
// Whereas the other |Check...()| functions are usually used with integral typs
|
||||
// or arrays of integral types, this one is used with Options structs for which
|
||||
// alignment has been explicitly been specified (using |MOJO_ALIGNAS()|), which
|
||||
@ -75,13 +75,13 @@ template void MOJO_SYSTEM_IMPL_EXPORT
|
||||
#if defined(COMPILER_MSVC) && defined(ARCH_CPU_32_BITS)
|
||||
template <>
|
||||
void MOJO_SYSTEM_IMPL_EXPORT
|
||||
CheckUserPointerWithSize<8>(const void* pointer, size_t size) {
|
||||
CheckUserPointerWithSize<8>(const void* pointer, size_t size) {
|
||||
CHECK(size == 0 ||
|
||||
(!!pointer && reinterpret_cast<uintptr_t>(pointer) % 8 == 0));
|
||||
}
|
||||
#else
|
||||
template void MOJO_SYSTEM_IMPL_EXPORT
|
||||
CheckUserPointerWithSize<8>(const void*, size_t);
|
||||
CheckUserPointerWithSize<8>(const void*, size_t);
|
||||
#endif
|
||||
|
||||
} // namespace internal
|
||||
|
@ -53,13 +53,13 @@ void MOJO_SYSTEM_IMPL_EXPORT CheckUserPointer(const void* pointer);
|
||||
// a buffer of |count| elements of the given size and alignment (both in bytes).
|
||||
template <size_t size, size_t alignment>
|
||||
void MOJO_SYSTEM_IMPL_EXPORT
|
||||
CheckUserPointerWithCount(const void* pointer, size_t count);
|
||||
CheckUserPointerWithCount(const void* pointer, size_t count);
|
||||
|
||||
// Checks (insofar as appropriate/possible) that |pointer| is a valid pointer to
|
||||
// a buffer of the given size and alignment (both in bytes).
|
||||
template <size_t alignment>
|
||||
void MOJO_SYSTEM_IMPL_EXPORT
|
||||
CheckUserPointerWithSize(const void* pointer, size_t size);
|
||||
CheckUserPointerWithSize(const void* pointer, size_t size);
|
||||
|
||||
} // namespace internal
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
#include "base/compiler_specific.h"
|
||||
#include "base/logging.h"
|
||||
#include "mojo/edk/system/constants.h"
|
||||
#include "mojo/edk/system/configuration.h"
|
||||
#include "mojo/edk/system/transport_data.h"
|
||||
|
||||
namespace mojo {
|
||||
@ -38,23 +38,13 @@ struct MessageInTransit::PrivateStructForCompileAsserts {
|
||||
// The size of |Header| must be a multiple of the alignment.
|
||||
static_assert(sizeof(Header) % kMessageAlignment == 0,
|
||||
"sizeof(MessageInTransit::Header) invalid");
|
||||
// Avoid dangerous situations, but making sure that the size of the "header" +
|
||||
// the size of the data fits into a 31-bit number.
|
||||
static_assert(static_cast<uint64_t>(sizeof(Header)) + kMaxMessageNumBytes <=
|
||||
0x7fffffffULL,
|
||||
"kMaxMessageNumBytes too big");
|
||||
|
||||
// We assume (to avoid extra rounding code) that the maximum message (data)
|
||||
// size is a multiple of the alignment.
|
||||
static_assert(kMaxMessageNumBytes % kMessageAlignment == 0,
|
||||
"kMessageAlignment not a multiple of alignment");
|
||||
};
|
||||
|
||||
MessageInTransit::View::View(size_t message_size, const void* buffer)
|
||||
: buffer_(buffer) {
|
||||
size_t next_message_size = 0;
|
||||
DCHECK(MessageInTransit::GetNextMessageSize(
|
||||
buffer_, message_size, &next_message_size));
|
||||
DCHECK(MessageInTransit::GetNextMessageSize(buffer_, message_size,
|
||||
&next_message_size));
|
||||
DCHECK_EQ(message_size, next_message_size);
|
||||
// This should be equivalent.
|
||||
DCHECK_EQ(message_size, total_size());
|
||||
@ -62,18 +52,29 @@ MessageInTransit::View::View(size_t message_size, const void* buffer)
|
||||
|
||||
bool MessageInTransit::View::IsValid(size_t serialized_platform_handle_size,
|
||||
const char** error_message) const {
|
||||
size_t max_message_num_bytes = GetConfiguration().max_message_num_bytes;
|
||||
// Avoid dangerous situations, but making sure that the size of the "header" +
|
||||
// the size of the data fits into a 31-bit number.
|
||||
DCHECK_LE(static_cast<uint64_t>(sizeof(Header)) + max_message_num_bytes,
|
||||
0x7fffffffULL)
|
||||
<< "GetConfiguration().max_message_num_bytes too big";
|
||||
|
||||
// We assume (to avoid extra rounding code) that the maximum message (data)
|
||||
// size is a multiple of the alignment.
|
||||
DCHECK_EQ(max_message_num_bytes % kMessageAlignment, 0U)
|
||||
<< "GetConfiguration().max_message_num_bytes not a multiple of alignment";
|
||||
|
||||
// Note: This also implies a check on the |main_buffer_size()|, which is just
|
||||
// |RoundUpMessageAlignment(sizeof(Header) + num_bytes())|.
|
||||
if (num_bytes() > kMaxMessageNumBytes) {
|
||||
if (num_bytes() > max_message_num_bytes) {
|
||||
*error_message = "Message data payload too large";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (transport_data_buffer_size() > 0) {
|
||||
const char* e =
|
||||
TransportData::ValidateBuffer(serialized_platform_handle_size,
|
||||
transport_data_buffer(),
|
||||
transport_data_buffer_size());
|
||||
const char* e = TransportData::ValidateBuffer(
|
||||
serialized_platform_handle_size, transport_data_buffer(),
|
||||
transport_data_buffer_size());
|
||||
if (e) {
|
||||
*error_message = e;
|
||||
return false;
|
||||
@ -93,8 +94,7 @@ MessageInTransit::MessageInTransit(Type type,
|
||||
ConstructorHelper(type, subtype, num_bytes);
|
||||
if (bytes) {
|
||||
memcpy(MessageInTransit::bytes(), bytes, num_bytes);
|
||||
memset(static_cast<char*>(MessageInTransit::bytes()) + num_bytes,
|
||||
0,
|
||||
memset(static_cast<char*>(MessageInTransit::bytes()) + num_bytes, 0,
|
||||
main_buffer_size_ - sizeof(Header) - num_bytes);
|
||||
} else {
|
||||
memset(MessageInTransit::bytes(), 0, main_buffer_size_ - sizeof(Header));
|
||||
@ -195,7 +195,7 @@ void MessageInTransit::SerializeAndCloseDispatchers(Channel* channel) {
|
||||
void MessageInTransit::ConstructorHelper(Type type,
|
||||
Subtype subtype,
|
||||
uint32_t num_bytes) {
|
||||
DCHECK_LE(num_bytes, kMaxMessageNumBytes);
|
||||
DCHECK_LE(num_bytes, GetConfiguration().max_message_num_bytes);
|
||||
|
||||
// |total_size| is updated below, from the other values.
|
||||
header()->type = type;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user