From 57e160b7ff81991ab443552f6bc9530449f9c138 Mon Sep 17 00:00:00 2001 From: "venu.musham" Date: Mon, 20 May 2019 15:14:32 +0530 Subject: [PATCH 1/2] Subresource loading via Network Service. Add support to load subresources on Network service. - Create socketpair between network and renderer for data communication for non broker processes. - load data via mojo messages - create channels between network, browser and renderer, browser. Signed-off-by: venu.musham --- .../loader/mojo_async_resource_handler.cc | 7 ----- content/child/child_thread_impl.cc | 25 ++++++++++++----- content/child/resource_dispatcher.cc | 3 -- content/child/runtime_features.cc | 8 ------ .../service_manager/child_connection.cc | 8 ++++-- .../incoming_broker_client_invitation.cc | 11 ++++---- .../incoming_broker_client_invitation.h | 6 ++-- mojo/edk/embedder/tcp_platform_handle_utils.h | 4 ++- .../tcp_platform_handle_utils_posix.cc | 18 ++++++++++-- mojo/edk/system/broker.h | 2 +- mojo/edk/system/broker_posix.cc | 4 +-- mojo/edk/system/core.cc | 4 +-- mojo/edk/system/core.h | 2 +- mojo/edk/system/node_controller.cc | 28 +++++++++++++++++-- mojo/edk/system/node_controller.h | 2 +- 15 files changed, 85 insertions(+), 47 deletions(-) diff --git a/content/browser/loader/mojo_async_resource_handler.cc b/content/browser/loader/mojo_async_resource_handler.cc index 104553c9454..d1772e1a4ae 100644 --- a/content/browser/loader/mojo_async_resource_handler.cc +++ b/content/browser/loader/mojo_async_resource_handler.cc @@ -324,15 +324,8 @@ void MojoAsyncResourceHandler::OnReadCompleted( if (response_body_consumer_handle_.is_valid()) { // Send the data pipe on the first OnReadCompleted call. -#if defined(CASTANETS) - if (!base::Castanets::IsEnabled()) { - url_loader_client_->OnStartLoadingResponseBody( - std::move(response_body_consumer_handle_)); - } -#else url_loader_client_->OnStartLoadingResponseBody( std::move(response_body_consumer_handle_)); -#endif response_body_consumer_handle_.reset(); } diff --git a/content/child/child_thread_impl.cc b/content/child/child_thread_impl.cc index 52932a742c4..807723d73eb 100644 --- a/content/child/child_thread_impl.cc +++ b/content/child/child_thread_impl.cc @@ -318,9 +318,13 @@ InitializeMojoIPCChannel() { if (!platform_channel.is_valid()) return nullptr; + std::string type = + base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( + switches::kProcessType); + return mojo::edk::IncomingBrokerClientInvitation::Accept( mojo::edk::ConnectionParams(mojo::edk::TransportProtocol::kLegacy, - std::move(platform_channel))); + std::move(platform_channel)), type); } class ChannelBootstrapFilter : public ConnectionFilter { @@ -503,12 +507,19 @@ void ChildThreadImpl::Init(const Options& options) { #if defined(CASTANETS) std::string service_request_token; if (base::Castanets::IsEnabled()) { - service_request_token = "castanets_service_request"; - // workaround - base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( - switches::kRendererClientId, std::to_string(1)); - base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( - switches::kNumRasterThreads, std::to_string(4)); + std::string process_type_str = + base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( + switches::kProcessType); + if (process_type_str == switches::kUtilityProcess) + service_request_token = "castanets_service_utility_request"; + else { + service_request_token = "castanets_service_renderer_request"; + // workaround + base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( + switches::kRendererClientId, std::to_string(1)); + base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( + switches::kNumRasterThreads, std::to_string(4)); + } } else { service_request_token = base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( diff --git a/content/child/resource_dispatcher.cc b/content/child/resource_dispatcher.cc index 4a4edbb74c1..e3911867e55 100644 --- a/content/child/resource_dispatcher.cc +++ b/content/child/resource_dispatcher.cc @@ -298,9 +298,6 @@ void ResourceDispatcher::OnReceivedData(int request_id, CHECK(data_start); CHECK(data_start + data_offset); const char* data_ptr = data_start + data_offset; - const uint8_t* start_ptr = static_cast(request_info->buffer->memory()) + data_offset; - std::vector bytes(start_ptr, start_ptr + data_length); - DVLOG(1) << " Renderer received data :" << reinterpret_cast(&bytes.front()); #if defined(CASTANETS) && !defined(NETWORK_SHARED_MEMORY) if (base::Castanets::IsEnabled()) { uint8_t* cpy_ptr = static_cast(request_info->buffer->memory()) + data_offset; diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc index 631852770b8..59f1d793e36 100644 --- a/content/child/runtime_features.cc +++ b/content/child/runtime_features.cc @@ -22,10 +22,6 @@ #include "ui/gl/gl_switches.h" #include "ui/native_theme/native_theme_features.h" -#if defined(CASTANETS) -#include "base/distributed_chromium_util.h" -#endif - using blink::WebRuntimeFeatures; namespace content { @@ -325,10 +321,6 @@ void SetRuntimeFeaturesDefaultsAndUpdateFromArgs( if (base::FeatureList::IsEnabled(features::kLoadingWithMojo) || base::FeatureList::IsEnabled(features::kNetworkService)) WebRuntimeFeatures::EnableLoadingWithMojo(true); -#if defined(CASTANETS) - if (base::Castanets::IsEnabled()) - WebRuntimeFeatures::EnableLoadingWithMojo(false); -#endif if (base::FeatureList::IsEnabled(features::kOutOfBlinkCORS)) WebRuntimeFeatures::EnableOutOfBlinkCORS(true); diff --git a/content/common/service_manager/child_connection.cc b/content/common/service_manager/child_connection.cc index 7596215db1a..3fd5187d6ff 100644 --- a/content/common/service_manager/child_connection.cc +++ b/content/common/service_manager/child_connection.cc @@ -126,8 +126,12 @@ ChildConnection::ChildConnection( // TODO(rockot): Use a constant name for this pipe attachment rather than a // randomly generated token. #if defined(CASTANETS) - if (base::Castanets::IsEnabled()) - service_token_ = "castanets_service_request"; + if (base::Castanets::IsEnabled()) { + if (child_identity.name() == "content_utility") + service_token_ = "castanets_service_utility_request"; + else + service_token_ = "castanets_service_renderer_request"; + } else service_token_ = mojo::edk::GenerateRandomToken(); #else diff --git a/mojo/edk/embedder/incoming_broker_client_invitation.cc b/mojo/edk/embedder/incoming_broker_client_invitation.cc index 80a3a264c24..a5f1b2bb003 100644 --- a/mojo/edk/embedder/incoming_broker_client_invitation.cc +++ b/mojo/edk/embedder/incoming_broker_client_invitation.cc @@ -19,9 +19,9 @@ IncomingBrokerClientInvitation::~IncomingBrokerClientInvitation() = default; // static std::unique_ptr -IncomingBrokerClientInvitation::Accept(ConnectionParams params) { +IncomingBrokerClientInvitation::Accept(ConnectionParams params, std::string type) { return base::WrapUnique( - new IncomingBrokerClientInvitation(std::move(params))); + new IncomingBrokerClientInvitation(std::move(params), type)); } // static @@ -33,7 +33,7 @@ IncomingBrokerClientInvitation::AcceptFromCommandLine( *base::CommandLine::ForCurrentProcess()); DCHECK(platform_channel.is_valid()); return base::WrapUnique(new IncomingBrokerClientInvitation( - ConnectionParams(protocol, std::move(platform_channel)))); + ConnectionParams(protocol, std::move(platform_channel)), "null")); } ScopedMessagePipeHandle IncomingBrokerClientInvitation::ExtractMessagePipe( @@ -42,9 +42,10 @@ ScopedMessagePipeHandle IncomingBrokerClientInvitation::ExtractMessagePipe( } IncomingBrokerClientInvitation::IncomingBrokerClientInvitation( - ConnectionParams params) { + ConnectionParams params, std::string type) { DCHECK(internal::g_core); - internal::g_core->AcceptBrokerClientInvitation(std::move(params)); + type_ = type; + internal::g_core->AcceptBrokerClientInvitation(std::move(params), type); } } // namespace edk diff --git a/mojo/edk/embedder/incoming_broker_client_invitation.h b/mojo/edk/embedder/incoming_broker_client_invitation.h index 79193ea5564..b57571e14c4 100644 --- a/mojo/edk/embedder/incoming_broker_client_invitation.h +++ b/mojo/edk/embedder/incoming_broker_client_invitation.h @@ -25,7 +25,7 @@ class MOJO_SYSTEM_IMPL_EXPORT IncomingBrokerClientInvitation { // Accepts an incoming invitation received via the connection medium in // |params|. static std::unique_ptr Accept( - ConnectionParams params); + ConnectionParams params, std::string type); // Accepts an incoming invitation from the command line. The command line is // expected to have a |PlatformChannelPair::kMojoPlatformChannelHandleSwitch| @@ -47,7 +47,9 @@ class MOJO_SYSTEM_IMPL_EXPORT IncomingBrokerClientInvitation { ScopedMessagePipeHandle ExtractMessagePipe(const std::string& name); private: - explicit IncomingBrokerClientInvitation(ConnectionParams params); + explicit IncomingBrokerClientInvitation(ConnectionParams params, std::string type); + + std::string type_; DISALLOW_COPY_AND_ASSIGN(IncomingBrokerClientInvitation); }; diff --git a/mojo/edk/embedder/tcp_platform_handle_utils.h b/mojo/edk/embedder/tcp_platform_handle_utils.h index 73d936816ce..dd36bf0c4d1 100644 --- a/mojo/edk/embedder/tcp_platform_handle_utils.h +++ b/mojo/edk/embedder/tcp_platform_handle_utils.h @@ -19,7 +19,9 @@ namespace edk { const size_t kCastanetsAudioSyncPort = 7000; const size_t kCastanetsSyncPort = 8880; const size_t kCastanetsUtilitySyncPort = 6000; -const size_t kCastanetsBrokerPort = 9990; +const size_t kCastanetsBrokerPortUtility = 9990; +const size_t kCastanetsBrokerPortRenderer = 9991; +const size_t kCastanetsNonBrokerPort = 9010; MOJO_SYSTEM_IMPL_EXPORT ScopedPlatformHandle CreateTCPClientHandle(size_t port); diff --git a/mojo/edk/embedder/tcp_platform_handle_utils_posix.cc b/mojo/edk/embedder/tcp_platform_handle_utils_posix.cc index 08cd828e41a..1cf9b8236ce 100644 --- a/mojo/edk/embedder/tcp_platform_handle_utils_posix.cc +++ b/mojo/edk/embedder/tcp_platform_handle_utils_posix.cc @@ -41,8 +41,22 @@ ScopedPlatformHandle CreateTCPSocket(bool needs_connection, int protocol) { } // namespace +static int +connect_retry(int sockfd, const struct sockaddr *addr, socklen_t len) +{ + int nsec; + for (nsec = 1; nsec <= 128; nsec <<= 1) { + if (connect(sockfd, addr, len) == 0) + return(0); + if (nsec <= 128/2) + sleep(nsec); + } + return(-1); +} ScopedPlatformHandle CreateTCPClientHandle(size_t port) { - std::string server_address = base::Castanets::ServerAddress(); + std::string server_address = "127.0.0.1"; + if (port!= mojo::edk::kCastanetsNonBrokerPort) + server_address = base::Castanets::ServerAddress(); struct addrinfo* result = NULL; int status = getaddrinfo(server_address.c_str(), NULL, NULL, &result); if (status == 0 && result != NULL) { @@ -66,7 +80,7 @@ ScopedPlatformHandle CreateTCPClientHandle(size_t port) { if (!handle.is_valid()) return ScopedPlatformHandle(); - if (HANDLE_EINTR(connect(handle.get().handle, + if (HANDLE_EINTR(connect_retry(handle.get().handle, reinterpret_cast(&unix_addr), unix_addr_len)) < 0) { PLOG(ERROR) << "connect " << handle.get().handle; diff --git a/mojo/edk/system/broker.h b/mojo/edk/system/broker.h index 1577972a6d4..71e7d3f2c45 100644 --- a/mojo/edk/system/broker.h +++ b/mojo/edk/system/broker.h @@ -20,7 +20,7 @@ class Broker { public: // Note: This is blocking, and will wait for the first message over // |platform_handle|. - explicit Broker(ScopedPlatformHandle platform_handle); + explicit Broker(ScopedPlatformHandle platform_handle, int port); ~Broker(); // Returns the platform handle that should be used to establish a NodeChannel diff --git a/mojo/edk/system/broker_posix.cc b/mojo/edk/system/broker_posix.cc index 9418a7c104c..e32c688cec0 100644 --- a/mojo/edk/system/broker_posix.cc +++ b/mojo/edk/system/broker_posix.cc @@ -87,7 +87,7 @@ Channel::MessagePtr WaitForBrokerMessage( } // namespace -Broker::Broker(ScopedPlatformHandle platform_handle) +Broker::Broker(ScopedPlatformHandle platform_handle, int port) : sync_channel_(std::move(platform_handle)) { CHECK(sync_channel_.is_valid()); @@ -103,7 +103,7 @@ Broker::Broker(ScopedPlatformHandle platform_handle) &incoming_platform_handles)) { #if defined(CASTANETS) if (base::Castanets::IsEnabled()) - parent_channel_ = mojo::edk::CreateTCPClientHandle(mojo::edk::kCastanetsBrokerPort); + parent_channel_ = mojo::edk::CreateTCPClientHandle(port); else parent_channel_ = ScopedPlatformHandle(incoming_platform_handles.front()); #else diff --git a/mojo/edk/system/core.cc b/mojo/edk/system/core.cc index 8e8e317065a..9bd623fd58b 100644 --- a/mojo/edk/system/core.cc +++ b/mojo/edk/system/core.cc @@ -217,10 +217,10 @@ void Core::SendBrokerClientInvitation( process_error_callback); } -void Core::AcceptBrokerClientInvitation(ConnectionParams connection_params) { +void Core::AcceptBrokerClientInvitation(ConnectionParams connection_params, std::string type) { RequestContext request_context; GetNodeController()->AcceptBrokerClientInvitation( - std::move(connection_params)); + std::move(connection_params), type); } uint64_t Core::ConnectToPeer(ConnectionParams connection_params, diff --git a/mojo/edk/system/core.h b/mojo/edk/system/core.h index b7a1d70a9fb..2553928f3ad 100644 --- a/mojo/edk/system/core.h +++ b/mojo/edk/system/core.h @@ -85,7 +85,7 @@ class MOJO_SYSTEM_IMPL_EXPORT Core { // Accepts a broker client invitation via |connection_params|. The other end // of the connection medium in |connection_params| must have been used by some // other process to send an OutgoingBrokerClientInvitation. - void AcceptBrokerClientInvitation(ConnectionParams connection_params); + void AcceptBrokerClientInvitation(ConnectionParams connection_params, std::string type); // Extracts a named message pipe endpoint from the broker client invitation // accepted by this process. Must only be called after diff --git a/mojo/edk/system/node_controller.cc b/mojo/edk/system/node_controller.cc index f25c9a75567..2954df06a1c 100644 --- a/mojo/edk/system/node_controller.cc +++ b/mojo/edk/system/node_controller.cc @@ -7,7 +7,9 @@ #include #include +#include "base/base_switches.h" #include "base/bind.h" +#include "base/command_line.h" #include "base/containers/queue.h" #include "base/location.h" #include "base/logging.h" @@ -18,6 +20,7 @@ #include "base/rand_util.h" #include "base/time/time.h" #include "base/timer/elapsed_timer.h" +#include "content/public/common/content_switches.h" #include "mojo/edk/embedder/embedder_internal.h" #include "mojo/edk/embedder/named_platform_channel_pair.h" #include "mojo/edk/embedder/named_platform_handle.h" @@ -233,7 +236,7 @@ void NodeController::SendBrokerClientInvitation( } void NodeController::AcceptBrokerClientInvitation( - ConnectionParams connection_params) { + ConnectionParams connection_params, std::string type) { #if defined(CASTANETS) if (!base::Castanets::IsEnabled()) DCHECK(!GetConfiguration().is_broker_process); @@ -242,7 +245,10 @@ void NodeController::AcceptBrokerClientInvitation( // Use the bootstrap channel for the broker and receive the node's channel // synchronously as the first message from the broker. base::ElapsedTimer timer; - broker_.reset(new Broker(connection_params.TakeChannelHandle())); + int port = mojo::edk::kCastanetsBrokerPortRenderer; + if (type == "utility") + port = mojo::edk::kCastanetsBrokerPortUtility; + broker_.reset(new Broker(connection_params.TakeChannelHandle(), port)); ScopedPlatformHandle platform_handle = broker_->GetParentPlatformHandle(); UMA_HISTOGRAM_TIMES("Mojo.System.GetParentPlatformHandleSyncTime", timer.Elapsed()); @@ -378,8 +384,10 @@ void NodeController::SendBrokerClientInvitationOnIOThread( bool channel_ok; if (base::Castanets::IsEnabled()) { - server_handle = mojo::edk::CreateTCPServerHandle(mojo::edk::kCastanetsBrokerPort); + static int port = mojo::edk::kCastanetsBrokerPortUtility; + server_handle = mojo::edk::CreateTCPServerHandle(port); client_handle = mojo::edk::CreateTCPDummyHandle(); + port = mojo::edk::kCastanetsBrokerPortRenderer; // BrokerHost owns itself. broker_host = @@ -1111,11 +1119,25 @@ void NodeController::OnIntroduce(const ports::NodeName& from_node, pending_peer_messages_.erase(name); return; } +#if defined(CASTANETS) + std::string process_type_str = + base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII("type"); + ScopedPlatformHandle handle; + if (process_type_str == "utility") + handle = mojo::edk::CreateTCPServerHandle(mojo::edk::kCastanetsNonBrokerPort); + else + handle = mojo::edk::CreateTCPClientHandle(mojo::edk::kCastanetsNonBrokerPort); + scoped_refptr channel = NodeChannel::Create( + this, + ConnectionParams(TransportProtocol::kLegacy, std::move(handle)), + io_task_runner_, ProcessErrorCallback()); +#else scoped_refptr channel = NodeChannel::Create( this, ConnectionParams(TransportProtocol::kLegacy, std::move(channel_handle)), io_task_runner_, ProcessErrorCallback()); +#endif DVLOG(1) << "Adding new peer " << name << " via parent introduction."; AddPeer(name, channel, true /* start_channel */); diff --git a/mojo/edk/system/node_controller.h b/mojo/edk/system/node_controller.h index 359a5c9e4fe..2b417be4847 100644 --- a/mojo/edk/system/node_controller.h +++ b/mojo/edk/system/node_controller.h @@ -83,7 +83,7 @@ class NodeController : public ports::NodeDelegate, const ProcessErrorCallback& process_error_callback); // Connects this node to the process which invited it to be a broker client. - void AcceptBrokerClientInvitation(ConnectionParams connection_params); + void AcceptBrokerClientInvitation(ConnectionParams connection_params, std::string type); // Connects this node to a peer node. On success, |port| will be merged with // the corresponding port in the peer node. Returns an ID that can be used to From 99e3a95792a58711eac3f1a781b684264f6d563c Mon Sep 17 00:00:00 2001 From: "venu.musham" Date: Mon, 20 May 2019 16:25:37 +0530 Subject: [PATCH 2/2] Introduce local shared memory support. Add support for local shared memory. Local shared memory between network and renderer process for sharing network resources loaded by url loader. This commit enables Network Service to run on renderer device without dependency on Network File System. To enable local shared memory, add below to gn args $ gn gen --args='enable_castanets=true enable_local_shared_memory=true' out/Default Signed-off-by: venu.musham --- base/files/file_util.h | 2 +- base/files/file_util_posix.cc | 10 +++--- base/memory/shared_memory_handle.h | 8 ++--- base/memory/shared_memory_handle_posix.cc | 12 +++---- base/memory/shared_memory_helper.cc | 6 ++-- base/memory/shared_memory_helper.h | 2 +- base/memory/shared_memory_posix.cc | 37 ++++++++++++++++----- build/config/BUILD.gn | 3 ++ build/config/features.gni | 1 + content/child/resource_dispatcher.cc | 2 +- content/common/resource_messages.h | 2 +- content/public/common/content_features.cc | 2 +- mojo/edk/embedder/platform_shared_buffer.cc | 6 ++-- mojo/edk/system/node_controller.cc | 32 +++++++++++------- mojo/public/cpp/system/platform_handle.cc | 2 +- 15 files changed, 79 insertions(+), 48 deletions(-) diff --git a/base/files/file_util.h b/base/files/file_util.h index 540b6ce5bd2..0ff9146562a 100644 --- a/base/files/file_util.h +++ b/base/files/file_util.h @@ -261,7 +261,7 @@ BASE_EXPORT FILE* CreateAndOpenTemporaryFile(FilePath* path); // Similar to CreateAndOpenTemporaryFile, but the file is created in |dir|. BASE_EXPORT FILE* CreateAndOpenTemporaryFileInDir(const FilePath& dir, -#if defined(NETWORK_SHARED_MEMORY) +#if defined(NETWORK_SHARED_MEMORY) || defined(LOCAL_SHARED_MEMORY) FilePath* path, int* id = NULL); #else diff --git a/base/files/file_util_posix.cc b/base/files/file_util_posix.cc index 8f2c3a950c4..f2659791fc0 100644 --- a/base/files/file_util_posix.cc +++ b/base/files/file_util_posix.cc @@ -56,7 +56,7 @@ #include #endif -#if defined(NETWORK_SHARED_MEMORY) +#if defined(NETWORK_SHARED_MEMORY) || defined(LOCAL_SHARED_MEMORY) #include "base/base_switches.h" #include "base/command_line.h" #endif @@ -143,7 +143,7 @@ std::string TempFileName() { #endif } -#if defined(NETWORK_SHARED_MEMORY) +#if defined(NETWORK_SHARED_MEMORY) || defined(LOCAL_SHARED_MEMORY) // Creates and opens a temporary file in |directory|, returning the // file descriptor. |path| is set to the temporary file path. // This function does NOT unlink() the file. @@ -689,7 +689,7 @@ bool CreateTemporaryFile(FilePath* path) { return true; } -#if defined(NETWORK_SHARED_MEMORY) +#if defined(NETWORK_SHARED_MEMORY) || defined(LOCAL_SHARED_MEMORY) FILE* CreateAndOpenTemporaryFileInDir(const FilePath& dir, FilePath* path, int* id) { int fd = CreateAndOpenFdForTemporaryFile(dir, path, id); #else @@ -713,7 +713,7 @@ bool CreateTemporaryFileInDir(const FilePath& dir, FilePath* temp_file) { static bool CreateTemporaryDirInDirImpl(const FilePath& base_dir, const FilePath::StringType& name_tmpl, -#if defined(NETWORK_SHARED_MEMORY) +#if defined(NETWORK_SHARED_MEMORY) || defined(LOCAL_SHARED_MEMORY) FilePath* new_dir, int *id = NULL) { #else @@ -1041,7 +1041,7 @@ bool GetShmemTempDir(bool executable, FilePath* path) { if (use_dev_shm) { // Use mountpoint for browser process and actual folder for renderer process // assuming NFS server is renderer and browser is its client. -#if !defined(NETWORK_SHARED_MEMORY) +#if !defined(NETWORK_SHARED_MEMORY) || defined(LOCAL_SHARED_MEMORY) *path = FilePath("/dev/shm"); #else std::string shared_memory_file_path; diff --git a/base/memory/shared_memory_handle.h b/base/memory/shared_memory_handle.h index e3bd5f22b49..ef181105960 100644 --- a/base/memory/shared_memory_handle.h +++ b/base/memory/shared_memory_handle.h @@ -159,7 +159,7 @@ class BASE_EXPORT SharedMemoryHandle { // when trying to map the SharedMemoryHandle at a later point in time. SharedMemoryHandle(const base::FileDescriptor& file_descriptor, size_t size, -#if !defined(NETWORK_SHARED_MEMORY) +#if !defined(NETWORK_SHARED_MEMORY) && !defined(LOCAL_SHARED_MEMORY) const base::UnguessableToken& guid); #else const base::UnguessableToken& guid, int shared_memory_file_id = 0); @@ -169,7 +169,7 @@ class BASE_EXPORT SharedMemoryHandle { // service. // Passing the wrong |size| has no immediate consequence, but may cause errors // when trying to map the SharedMemoryHandle at a later point in time. -#if !defined(NETWORK_SHARED_MEMORY) +#if !defined(NETWORK_SHARED_MEMORY)&& !defined(LOCAL_SHARED_MEMORY) static SharedMemoryHandle ImportHandle(int fd, size_t size); #else static SharedMemoryHandle ImportHandle(int fd, size_t size, int shared_memory_file_id = 0); @@ -182,7 +182,7 @@ class BASE_EXPORT SharedMemoryHandle { // unless the caller is careful. int Release(); #endif -#if defined(NETWORK_SHARED_MEMORY) +#if defined(NETWORK_SHARED_MEMORY) || defined(LOCAL_SHARED_MEMORY) int GetMemoryFileId() const { return shared_memory_file_id_; } void SetMemoryFileId(int id) { shared_memory_file_id_ = id; } #endif @@ -228,7 +228,7 @@ class BASE_EXPORT SharedMemoryHandle { // The size of the region referenced by the SharedMemoryHandle. size_t size_ = 0; -#if defined(NETWORK_SHARED_MEMORY) +#if defined(NETWORK_SHARED_MEMORY) || defined(LOCAL_SHARED_MEMORY) int shared_memory_file_id_; #endif }; diff --git a/base/memory/shared_memory_handle_posix.cc b/base/memory/shared_memory_handle_posix.cc index 5ae06f10442..3747d97f33a 100644 --- a/base/memory/shared_memory_handle_posix.cc +++ b/base/memory/shared_memory_handle_posix.cc @@ -21,19 +21,19 @@ SharedMemoryHandle::SharedMemoryHandle() = default; SharedMemoryHandle::SharedMemoryHandle( const base::FileDescriptor& file_descriptor, size_t size, -#if !defined(NETWORK_SHARED_MEMORY) +#if !defined(NETWORK_SHARED_MEMORY) && !defined(LOCAL_SHARED_MEMORY) const base::UnguessableToken& guid) #else const base::UnguessableToken& guid, int shared_memory_file_id) #endif : file_descriptor_(file_descriptor), guid_(guid), size_(size) { -#if defined(NETWORK_SHARED_MEMORY) +#if defined(NETWORK_SHARED_MEMORY) || defined(LOCAL_SHARED_MEMORY) shared_memory_file_id_ = shared_memory_file_id; #endif } // static -#if !defined(NETWORK_SHARED_MEMORY) +#if !defined(NETWORK_SHARED_MEMORY) && !defined(LOCAL_SHARED_MEMORY) SharedMemoryHandle SharedMemoryHandle::ImportHandle(int fd, size_t size) { #else SharedMemoryHandle SharedMemoryHandle::ImportHandle(int fd, size_t size, int shared_memory_file_id) { @@ -43,7 +43,7 @@ SharedMemoryHandle SharedMemoryHandle::ImportHandle(int fd, size_t size, int sha handle.file_descriptor_.auto_close = false; handle.guid_ = UnguessableToken::Create(); handle.size_ = size; -#if defined(NETWORK_SHARED_MEMORY) +#if defined(NETWORK_SHARED_MEMORY) || defined(LOCAL_SHARED_MEMORY) handle.shared_memory_file_id_ = shared_memory_file_id; #endif return handle; @@ -82,7 +82,7 @@ SharedMemoryHandle SharedMemoryHandle::Duplicate() const { #if defined(CASTANETS) if (base::Castanets::IsEnabled() && file_descriptor_.fd == 0) { -#if defined(NETWORK_SHARED_MEMORY) +#if defined(NETWORK_SHARED_MEMORY) || defined(LOCAL_SHARED_MEMORY) return SharedMemoryHandle(FileDescriptor(0, true), GetSize(), GetGUID(), GetMemoryFileId()); #else return SharedMemoryHandle(FileDescriptor(0, true), GetSize(), GetGUID()); @@ -94,7 +94,7 @@ SharedMemoryHandle SharedMemoryHandle::Duplicate() const { if (duped_handle < 0) return SharedMemoryHandle(); return SharedMemoryHandle(FileDescriptor(duped_handle, true), GetSize(), -#if defined(NETWORK_SHARED_MEMORY) +#if defined(NETWORK_SHARED_MEMORY) || defined(LOCAL_SHARED_MEMORY) GetGUID(), GetMemoryFileId()); #else GetGUID()); diff --git a/base/memory/shared_memory_helper.cc b/base/memory/shared_memory_helper.cc index 1c2d467aba3..5f3c2ded7b9 100644 --- a/base/memory/shared_memory_helper.cc +++ b/base/memory/shared_memory_helper.cc @@ -32,7 +32,7 @@ using ScopedPathUnlinker = bool CreateAnonymousSharedMemory(const SharedMemoryCreateOptions& options, ScopedFILE* fp, ScopedFD* readonly_fd, -#if defined(NETWORK_SHARED_MEMORY) +#if defined(NETWORK_SHARED_MEMORY) || defined(LOCAL_SHARED_MEMORY) FilePath* path, int *id) { #else @@ -49,7 +49,7 @@ bool CreateAnonymousSharedMemory(const SharedMemoryCreateOptions& options, if (!GetShmemTempDir(options.executable, &directory)) return false; -#if defined(NETWORK_SHARED_MEMORY) +#if defined(NETWORK_SHARED_MEMORY) || defined(LOCAL_SHARED_MEMORY) fp->reset(base::CreateAndOpenTemporaryFileInDir(directory, path, id)); #else fp->reset(base::CreateAndOpenTemporaryFileInDir(directory, path)); @@ -61,7 +61,7 @@ bool CreateAnonymousSharedMemory(const SharedMemoryCreateOptions& options, // Deleting the file prevents anyone else from mapping it in (making it // private), and prevents the need for cleanup (once the last fd is // closed, it is truly freed). -#if !defined(NETWORK_SHARED_MEMORY) +#if !defined(NETWORK_SHARED_MEMORY) && !defined(LOCAL_SHARED_MEMORY) path_unlinker.reset(path); #endif diff --git a/base/memory/shared_memory_helper.h b/base/memory/shared_memory_helper.h index 0357a25a4da..3dc5873bf47 100644 --- a/base/memory/shared_memory_helper.h +++ b/base/memory/shared_memory_helper.h @@ -20,7 +20,7 @@ namespace base { bool CreateAnonymousSharedMemory(const SharedMemoryCreateOptions& options, ScopedFILE* fp, ScopedFD* readonly_fd, -#if defined(NETWORK_SHARED_MEMORY) +#if defined(NETWORK_SHARED_MEMORY) || defined(LOCAL_SHARED_MEMORY) FilePath* path, int* id = NULL); #else diff --git a/base/memory/shared_memory_posix.cc b/base/memory/shared_memory_posix.cc index 9c697f34f32..8b6ff2d18aa 100644 --- a/base/memory/shared_memory_posix.cc +++ b/base/memory/shared_memory_posix.cc @@ -11,6 +11,8 @@ #include #include +#include "base/base_switches.h" +#include "base/command_line.h" #include "base/files/file_util.h" #include "base/files/scoped_file.h" #include "base/logging.h" @@ -25,6 +27,7 @@ #include "base/trace_event/trace_event.h" #include "base/unguessable_token.h" #include "build/build_config.h" +#include "content/public/common/content_switches.h" #if defined(OS_ANDROID) #include "base/os_compat_android.h" @@ -105,11 +108,11 @@ bool SharedMemory::Create(const SharedMemoryCreateOptions& options, int sid) { ScopedFD readonly_fd; FilePath path; -#if defined(NETWORK_SHARED_MEMORY) +#if defined(NETWORK_SHARED_MEMORY) || defined(LOCAL_SHARED_MEMORY) int shared_memory_file_id = sid; #endif if (options.name_deprecated == NULL || options.name_deprecated->empty()) { -#if defined(NETWORK_SHARED_MEMORY) +#if defined(NETWORK_SHARED_MEMORY) || defined(LOCAL_SHARED_MEMORY) bool result = CreateAnonymousSharedMemory(options, &fp, &readonly_fd, &path, &shared_memory_file_id); #else @@ -125,7 +128,7 @@ bool SharedMemory::Create(const SharedMemoryCreateOptions& options, int sid) { // Make sure that the file is opened without any permission // to other users on the system. -#if defined(NETWORK_SHARED_MEMORY) +#if defined(NETWORK_SHARED_MEMORY) && !defined(LOCAL_SHARED_MEMORY) const mode_t kOwnerOnly = S_IRUSR | S_IWUSR | S_IRWXU| S_IRWXO; #else const mode_t kOwnerOnly = S_IRUSR | S_IWUSR; @@ -153,7 +156,7 @@ bool SharedMemory::Create(const SharedMemoryCreateOptions& options, int sid) { // Check that the current user owns the file. // If uid != euid, then a more complex permission model is used and this // API is not appropriate. -#if !defined(NETWORK_SHARED_MEMORY) +#if !defined(NETWORK_SHARED_MEMORY) && !defined(LOCAL_SHARED_MEMORY) const uid_t real_uid = getuid(); const uid_t effective_uid = geteuid(); struct stat sb; @@ -215,7 +218,7 @@ bool SharedMemory::Create(const SharedMemoryCreateOptions& options, int sid) { int readonly_mapped_file = -1; bool result = PrepareMapFile(std::move(fp), std::move(readonly_fd), &mapped_file, &readonly_mapped_file); -#if !defined(NETWORK_SHARED_MEMORY) +#if !defined(NETWORK_SHARED_MEMORY) && !defined(LOCAL_SHARED_MEMORY) shm_ = SharedMemoryHandle(base::FileDescriptor(mapped_file, false), options.size, UnguessableToken::Create()); readonly_shm_ = @@ -305,8 +308,14 @@ bool SharedMemory::MapAt(off_t offset, size_t bytes) { #endif #if defined(CASTANETS) + std::string process_type_str = + base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII("type"); if (Castanets::IsEnabled()) - memory_ = new uint8_t[bytes]; + if (process_type_str == "renderer" || process_type_str == "utility") + memory_ = mmap(NULL, bytes, PROT_READ | (read_only_ ? 0 : PROT_WRITE), + MAP_SHARED, shm_.GetHandle(), offset); + else + memory_ = new uint8_t[bytes]; else { memory_ = mmap(NULL, bytes, PROT_READ | (read_only_ ? 0 : PROT_WRITE), MAP_SHARED, shm_.GetHandle(), offset); @@ -343,8 +352,13 @@ bool SharedMemory::Unmap() { SharedMemoryTracker::GetInstance()->DecrementMemoryUsage(*this); #if defined(CASTANETS) + std::string process_type_str = + base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII("type"); if (Castanets::IsEnabled()) - delete [] memory_; + if (process_type_str == "renderer" || process_type_str == "utility") + munmap(memory_, mapped_size_); + else + delete [] memory_; #else munmap(memory_, mapped_size_); #endif @@ -363,8 +377,13 @@ SharedMemoryHandle SharedMemory::TakeHandle() { handle_copy.SetOwnershipPassesToIPC(true); shm_ = SharedMemoryHandle(); #if defined(CASTANETS) + std::string process_type_str = + base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII("type"); if (Castanets::IsEnabled()) - delete [] memory_; + if (process_type_str == "renderer" || process_type_str == "utility") + munmap(memory_, mapped_size_); + else + delete [] memory_; #endif memory_ = nullptr; mapped_size_ = 0; @@ -399,7 +418,7 @@ bool SharedMemory::FilePathForMemoryName(const std::string& mem_name, #if defined(GOOGLE_CHROME_BUILD) std::string name_base = std::string("com.google.Chrome"); -#elif defined(NETWORK_SHARED_MEMORY) +#elif defined(NETWORK_SHARED_MEMORY) || defined(LOCAL_SHARED_MEMORY) std::string name_base = std::string(".org.chromium.Chromium"); #else std::string name_base = std::string("org.chromium.Chromium"); diff --git a/build/config/BUILD.gn b/build/config/BUILD.gn index 12460dfa72a..b8451107440 100644 --- a/build/config/BUILD.gn +++ b/build/config/BUILD.gn @@ -64,6 +64,9 @@ config("feature_flags") { if (enable_network_shared_memory) { defines += [ "NETWORK_SHARED_MEMORY" ] } + if (enable_local_shared_memory) { + defines += [ "LOCAL_SHARED_MEMORY" ] + } if (dcheck_always_on) { defines += [ "DCHECK_ALWAYS_ON=1" ] } diff --git a/build/config/features.gni b/build/config/features.gni index c84adfa465b..c2b3c39feba 100644 --- a/build/config/features.gni +++ b/build/config/features.gni @@ -25,6 +25,7 @@ declare_args() { # Enables CASTANETS. enable_castanets = false enable_network_shared_memory = false + enable_local_shared_memory = false # Enables proprietary codecs and demuxers; e.g. H264, AAC, MP3, and MP4. # We always build Google Chrome and Chromecast with proprietary codecs. diff --git a/content/child/resource_dispatcher.cc b/content/child/resource_dispatcher.cc index e3911867e55..b09d01c9cdc 100644 --- a/content/child/resource_dispatcher.cc +++ b/content/child/resource_dispatcher.cc @@ -227,7 +227,7 @@ void ResourceDispatcher::OnSetDataBuffer(int request_id, CHECK((shm_valid && shm_size > 0) || (!shm_valid && !shm_size)); } #endif -#if defined(NETWORK_SHARED_MEMORY) +#if defined(NETWORK_SHARED_MEMORY) || defined(LOCAL_SHARED_MEMORY) request_info->buffer.reset( new base::SharedMemory(shm_handle, true)); // read only if(request_info->buffer->handle().GetHandle() == 0) diff --git a/content/common/resource_messages.h b/content/common/resource_messages.h index b0521372464..3b9b22fd9fc 100644 --- a/content/common/resource_messages.h +++ b/content/common/resource_messages.h @@ -345,7 +345,7 @@ IPC_MESSAGE_CONTROL4(ResourceMsg_SetDataBuffer, // Sent when some data from a resource request is ready. The data offset and // length specify a byte range into the shared memory buffer provided by the // SetDataBuffer message. -#if defined(CASTANETS) && !defined(NETWORK_SHARED_MEMORY) +#if (defined(CASTANETS) && !defined(NETWORK_SHARED_MEMORY)) IPC_MESSAGE_CONTROL5(ResourceMsg_DataReceived, int /* request_id */, int /* data_offset */, diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc index ddb4383fada..060301b76fb 100644 --- a/content/public/common/content_features.cc +++ b/content/public/common/content_features.cc @@ -159,7 +159,7 @@ const base::Feature kMemoryCoordinator { // Enables the network service. const base::Feature kNetworkService{"NetworkService", - base::FEATURE_DISABLED_BY_DEFAULT}; + base::FEATURE_ENABLED_BY_DEFAULT}; // Kill switch for Web Notification content images. const base::Feature kNotificationContentImage{"NotificationContentImage", diff --git a/mojo/edk/embedder/platform_shared_buffer.cc b/mojo/edk/embedder/platform_shared_buffer.cc index 256efde0cd7..46f40b8bf52 100644 --- a/mojo/edk/embedder/platform_shared_buffer.cc +++ b/mojo/edk/embedder/platform_shared_buffer.cc @@ -127,7 +127,7 @@ void PlatformSharedBuffer::FlushFS() { } int PlatformSharedBuffer::GetMemoryFileId() const { -#if defined(NETWORK_SHARED_MEMORY) +#if defined(NETWORK_SHARED_MEMORY) || defined(LOCAL_SHARED_MEMORY) return shared_memory_->handle().GetMemoryFileId(); #else return 0; @@ -272,7 +272,7 @@ bool PlatformSharedBuffer::InitFromPlatformHandle( base::SharedMemoryHandle handle = base::SharedMemoryHandle( platform_handle.release().as_handle(), num_bytes_, guid); #else -#if defined(NETWORK_SHARED_MEMORY) +#if defined(NETWORK_SHARED_MEMORY) || defined(LOCAL_SHARED_MEMORY) base::SharedMemoryHandle handle( base::FileDescriptor(platform_handle.release().handle, false), num_bytes_, guid, sid); @@ -284,7 +284,7 @@ bool PlatformSharedBuffer::InitFromPlatformHandle( #endif shared_memory_.reset(new base::SharedMemory(handle, read_only_)); -#if defined(NETWORK_SHARED_MEMORY) +#if defined(NETWORK_SHARED_MEMORY) || defined(LOCAL_SHARED_MEMORY) if (shared_memory_->handle().GetHandle() == 0) { std::string mid = std::string("U") + std::to_string(handle.GetMemoryFileId()); diff --git a/mojo/edk/system/node_controller.cc b/mojo/edk/system/node_controller.cc index 2954df06a1c..2812d69abff 100644 --- a/mojo/edk/system/node_controller.cc +++ b/mojo/edk/system/node_controller.cc @@ -1120,18 +1120,26 @@ void NodeController::OnIntroduce(const ports::NodeName& from_node, return; } #if defined(CASTANETS) - std::string process_type_str = - base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII("type"); - ScopedPlatformHandle handle; - if (process_type_str == "utility") - handle = mojo::edk::CreateTCPServerHandle(mojo::edk::kCastanetsNonBrokerPort); - else - handle = mojo::edk::CreateTCPClientHandle(mojo::edk::kCastanetsNonBrokerPort); - - scoped_refptr channel = NodeChannel::Create( - this, - ConnectionParams(TransportProtocol::kLegacy, std::move(handle)), - io_task_runner_, ProcessErrorCallback()); + scoped_refptr channel; + if (base::Castanets::IsEnabled()) { + std::string process_type_str = + base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII("type"); + ScopedPlatformHandle handle; + if (process_type_str == "utility") + handle = mojo::edk::CreateTCPServerHandle(mojo::edk::kCastanetsNonBrokerPort); + else + handle = mojo::edk::CreateTCPClientHandle(mojo::edk::kCastanetsNonBrokerPort); + + channel = NodeChannel::Create( + this, + ConnectionParams(TransportProtocol::kLegacy, std::move(handle)), + io_task_runner_, ProcessErrorCallback()); + } else { + channel = NodeChannel::Create( + this, + ConnectionParams(TransportProtocol::kLegacy, std::move(channel_handle)), + io_task_runner_, ProcessErrorCallback()); + } #else scoped_refptr channel = NodeChannel::Create( this, diff --git a/mojo/public/cpp/system/platform_handle.cc b/mojo/public/cpp/system/platform_handle.cc index 7816ed4ba4c..0d1b7a8e872 100644 --- a/mojo/public/cpp/system/platform_handle.cc +++ b/mojo/public/cpp/system/platform_handle.cc @@ -89,7 +89,7 @@ ScopedSharedBufferHandle WrapSharedMemoryHandle( guid.low = memory_handle.GetGUID().GetLowForSerialization(); MojoHandle mojo_handle; int sid = 0; -#if defined(NETWORK_SHARED_MEMORY) +#if defined(NETWORK_SHARED_MEMORY) || defined(LOCAL_SHARED_MEMORY) sid = memory_handle.GetMemoryFileId(); #endif MojoResult result = MojoWrapPlatformSharedBufferHandle(