diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-01-31 16:33:43 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-02-06 16:33:22 +0000 |
commit | da51f56cc21233c2d30f0fe0d171727c3102b2e0 (patch) | |
tree | 4e579ab70ce4b19bee7984237f3ce05a96d59d83 /chromium/ipc | |
parent | c8c2d1901aec01e934adf561a9fdf0cc776cdef8 (diff) | |
download | qtwebengine-chromium-da51f56cc21233c2d30f0fe0d171727c3102b2e0.tar.gz |
BASELINE: Update Chromium to 65.0.3525.40
Also imports missing submodules
Change-Id: I36901b7c6a325cda3d2c10cedb2186c25af3b79b
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/ipc')
-rw-r--r-- | chromium/ipc/README.md | 195 | ||||
-rw-r--r-- | chromium/ipc/SECURITY_OWNERS | 12 | ||||
-rw-r--r-- | chromium/ipc/ipc_channel_mojo.cc | 4 | ||||
-rw-r--r-- | chromium/ipc/ipc_channel_mojo.h | 1 | ||||
-rw-r--r-- | chromium/ipc/ipc_channel_proxy.h | 4 | ||||
-rw-r--r-- | chromium/ipc/ipc_message.h | 2 | ||||
-rw-r--r-- | chromium/ipc/ipc_message_pipe_reader.cc | 17 | ||||
-rw-r--r-- | chromium/ipc/ipc_message_pipe_reader.h | 1 | ||||
-rw-r--r-- | chromium/ipc/ipc_message_start.h | 5 | ||||
-rw-r--r-- | chromium/ipc/ipc_message_utils.cc | 14 | ||||
-rw-r--r-- | chromium/ipc/ipc_mojo_bootstrap_unittest.cc | 124 | ||||
-rw-r--r-- | chromium/ipc/ipc_platform_file.cc | 2 | ||||
-rw-r--r-- | chromium/ipc/ipc_sync_channel.cc | 31 | ||||
-rw-r--r-- | chromium/ipc/ipc_sync_message.h | 2 |
14 files changed, 352 insertions, 62 deletions
diff --git a/chromium/ipc/README.md b/chromium/ipc/README.md index c30689a29a7..2e0cbe401fd 100644 --- a/chromium/ipc/README.md +++ b/chromium/ipc/README.md @@ -237,12 +237,18 @@ For example, any interfaces registered in can be acquired by a renderer as follows: ``` cpp -mojom::FooPtr foo; +mojom::LoggerPtr logger; content::RenderThread::Get()->GetConnector()->BindInterface( - content::mojom::kBrowserServiceName, &foo); -foo->DoSomePrettyCoolIPC(); + content::mojom::kBrowserServiceName, &logger); +logger->Log("Message to log here"); ``` +Usually `logger` will be saved in a field at construction time, so the +connection is only created once. There may be situations where you want to +create one connection per request, e.g. a new instance of the Mojo +implementation is created with some information about the request, and any +responses for this request go straight to that instance. + ### On Other Threads `Connector` instances can be created and asynchronously associated with each @@ -255,20 +261,21 @@ which may be used immediately and retained on that thread -- and asynchronously associate it with the main-thread `Connector` like so: ``` cpp -class Thinger { +class Logger { public: - explicit Thinger(scoped_refptr<base::TaskRunner> main_thread_task_runner) { + explicit Logger(scoped_refptr<base::TaskRunner> main_thread_task_runner) { service_manager::mojom::ConnectorRequest request; // Of course we could also retain |connector| if we intend to use it again. auto connector = service_manager::Connector::Create(&request); - connector->BindInterface("best_service_ever", &thinger_); - thinger_->DoTheThing(); + // Replace service_name with the name of the service to bind on, e.g. + // content::mojom::kBrowserServiceName. + connector->BindInterface("service_name", &logger_); + logger_->Log("Test Message."); - // Doesn't really matter when this happens, as long as it eventually - // happens. + // Doesn't matter when this happens, as long as it happens eventually. main_thread_task_runner->PostTask( - FROM_HERE, base::BindOnce(&Thinger::BindConnectorOnMainThread, + FROM_HERE, base::BindOnce(&Logger::BindConnectorOnMainThread, std::move(request))); } @@ -280,9 +287,9 @@ class Thinger { std::move(request)); } - mojom::ThingerPtr thinger_; + mojom::LoggerPtr logger_; - DISALLOW_COPY_AND_ASSIGN(Thinger); + DISALLOW_COPY_AND_ASSIGN(Logger); }; ``` @@ -339,6 +346,170 @@ interface connection between browser and renderer processes: As noted above, use of these registries is generally discouraged. +### Deciding Which Interface Registry to Use + +Once you have an implementation of a Mojo interface, the next thing to decide is +which registry and service to register it on. + +For browser/renderer communication, you can register your Mojo interface +implementation in either the Browser or Renderer process (whichever side the +interface was implemented on). Usually, this involves calling `AddInterface()` +on the correct registry, passing a method that takes the Mojo Request object +(e.g. `sample::mojom::LoggerRequest`) and binding it (e.g. +`mojo::MakeStrongBinding()`, `bindings_.AddBinding()`, etc). Then the class that +needs this API can call `BindInterface()` on the connector for that process, +e.g. +`RenderThread::Get()->GetConnector()->BindInterface(mojom::kBrowserServiceName, std::move(&mojo_interface_))`. + +**NOTE:** `content::ServiceManagerConnection::GetForProcess()` must be called in +the browser process on the main thread, and its connector can only be used on +the main thread; but you can clone connectors and move the clones around to +other threads. A `Connector` is only bound to the thread which first calls into +it. + +Depending on what resources you need access to, the main classes are: + +| Renderer Class | Corresponding Browser Class | Explanation | +|-----------------|-----------------------------|-------------------------------------------------------------------------------------------------------------------| +| `RenderFrame` | `RenderFrameHost` | A single frame. Use this for frame-to-frame messages. | +| `RenderView` | `RenderViewHost` | A view (conceptually a 'tab'). You cannot send Mojo messages to a `RenderView` directly, since frames in a tab can + be in multiple processes (and the classes are deprecated). Migrate these to `RenderFrame` instead, or see section + [Migrating IPC calls to `RenderView` or `RenderViewHost`](#UMigrating-IPC-calls-to-RenderView-or-RenderViewHost). | +| `RenderProcess` | `RenderProcessHost` | A process, containing multiple frames (probably from the same origin, but not always). | + +**NOTE:** Previously, classes that ended with `Host` were implemented on the +browser side; the equivalent classes on the renderer side had the same name +without the `Host` suffix. We have since deviated from this convention since +Mojo interfaces are not intended to prescribe where their endpoints live, so +future classes should omit such suffixes and just describe the interface they +are providing. + +Of course, any combination of the above is possible, e.g. `RenderProcessHost` +can register a Mojo interface that can be called by a `RenderFrame` (this would +be a way of the browser communicating with multiple frames at once). + +Once you know which class you want the implementation to be registered in, find +the corresponding `Impl` class (e.g. `RenderProcessImpl`). There should be a +`RegisterMojoInterfaces()` method where you can add calls to `AddInterface`, +e.g. For a strong binding: + +```cpp + registry->AddInterface(base::Bind(&Logger::Create, GetID())); +``` + +Then in `Logger` we add a static `Create()` method that takes the +`LoggerRequest` object: + +```cpp +// static +void Logger::Create(int render_process_id, + mojom::LoggerRequest request) { + mojo::MakeStrongBinding(std::make_unique<Logger>(render_process_id), + std::move(request)); +} +``` + +For a `BindingSet`, we can store a `std::unique_ptr<Logger>` on the +`RenderProcessHost` instead, e.g.: + +```cpp +// render_process_host_impl.h: +std::unique_ptr<Logger> logger_; + +// render_process_host_impl.cc: +logger_ = std::make_unique<Logger>(GetID()); +registry->AddInterface(base::Bind(&Logger::BindRequest, + base::Unretained(logger_.get()))); +``` + +Then in `Logger` we define the `BindRequest` method: + +```h +class Logger : public sample::mojom::Logger { + public: + explicit Logger(int render_process_id); + ~Logger() override; + + void BindRequest(mojom::LoggerRequest request); + + // sample::mojom::Logger: + void Log(const std::string& message) override; + void GetTail(GetTailCallback callback) override; + + private: + mojo::BindingSet<sample::mojom::Logger> bindings_; + + DISALLOW_COPY_AND_ASSIGN(Logger); +}; +``` + +```cpp +void Logger::BindRequest(mojom::LoggerRequest request) { + bindings_.AddBinding(this, std::move(request)); +} +``` + +#### Setting up Capabilities + +Once you've registered your interface, you need to add capabilities (resolved at +runtime) to the corresponding capabilities manifest json file. + +The service manifest files (which contain the capability spec) are located in +[/content/public/app/mojo/](/content/public/app/mojo/). As a general rule, the +file you want to edit is the service which *provides* the interface (the side +which instantiates the implementation), and the part of the file you want to add +the name of the interface to is the service which *calls* the interface (i.e. +the side containing `LoggerPtr`). + +You can usually just run your Mojo code and look at the error messages. The +errors look like: + +```sh +[ERROR:service_manager.cc(158)] Connection InterfaceProviderSpec prevented +service: content_renderer from binding interface: content::mojom::Logger +exposed by: content_browser +``` + +This means something in the renderer process (called "content_renderer") was +trying to bind to `content::mojom::Logger` in the browser process (called +"content_browser"). To add a capability for this, we need to find the json file +with the capabilities for "content_browser", and add our new interface with name +`content::mojom::Logger` to the "renderer" section. + +In this example, the capabilities for "content_browser" are implemented in +[content_browser_manifest.json](/content/public/app/mojo/content_browser_manifest.json). +It should look like: + +```json +{ + "name": "content_browser", + "display_name": "Content (browser process)", + "interface_provider_specs": { + "service_manager:connector": { + "provides": { + // ... + "renderer": [ + //... +``` + +To add permission for `content::mojom::Logger`, add the string +`"content::mojom::Logger"` to the "renderer" list. + +Similarly, if the error was: + +```sh +[ERROR:service_manager.cc(158)] Connection InterfaceProviderSpec prevented +service: content_browser from binding interface: content::mojom::Logger exposed +by: content_renderer +``` + +We would want the +`interface_provider_specs.service_manager:connector.provides.browser` section in +[content_renderer_manifest.json](/content/public/app/mojo/content_renderer_manifest.json) +(which defines the capabilities for `content_renderer`). + +TODO: Add more details on permission manifests here + ## Using Channel-associated Interfaces **NOTE**: Channel-associated interfaces are an interim solution to make the diff --git a/chromium/ipc/SECURITY_OWNERS b/chromium/ipc/SECURITY_OWNERS index 8bb1091dab6..9fe4dfb1829 100644 --- a/chromium/ipc/SECURITY_OWNERS +++ b/chromium/ipc/SECURITY_OWNERS @@ -1,9 +1,16 @@ -# Changes to IPC messages require a security review to avoid introducing -# new sandbox escapes. +# Changes to IPC messages require a security review to avoid introducing sandbox +# escapes. The shared memory implementation code needs review from a security +# owner. (Shared memory call sites should be reviewed as part of normal IPC +# security review.) +# +# Security team: If you are uncomfortable reviewing a particular bit of code +# yourself, don't hesitate to seek help from another security team member! +# Nobody knows everything, and the only way to learn is from experience. dcheng@chromium.org estark@chromium.org kenrb@chromium.org kerrnel@chromium.org +kinuko@chromium.org meacer@chromium.org mbarbella@chromium.org mkwst@chromium.org @@ -11,5 +18,6 @@ nasko@chromium.org ochang@chromium.org palmer@chromium.org rsesek@chromium.org +sammc@chromium.org tsepez@chromium.org wfh@chromium.org diff --git a/chromium/ipc/ipc_channel_mojo.cc b/chromium/ipc/ipc_channel_mojo.cc index 2dafc7b1268..d7ce34a9804 100644 --- a/chromium/ipc/ipc_channel_mojo.cc +++ b/chromium/ipc/ipc_channel_mojo.cc @@ -259,6 +259,10 @@ void ChannelMojo::OnMessageReceived(const Message& message) { listener_->OnBadMessageReceived(message); } +void ChannelMojo::OnBrokenDataReceived() { + listener_->OnBadMessageReceived(Message()); +} + // static MojoResult ChannelMojo::ReadFromMessageAttachmentSet( Message* message, diff --git a/chromium/ipc/ipc_channel_mojo.h b/chromium/ipc/ipc_channel_mojo.h index 340d80cdc7f..aa6ba435568 100644 --- a/chromium/ipc/ipc_channel_mojo.h +++ b/chromium/ipc/ipc_channel_mojo.h @@ -89,6 +89,7 @@ class IPC_EXPORT ChannelMojo : public Channel, // MessagePipeReader::Delegate void OnPeerPidReceived(int32_t peer_pid) override; void OnMessageReceived(const Message& message) override; + void OnBrokenDataReceived() override; void OnPipeError() override; void OnAssociatedInterfaceRequest( const std::string& name, diff --git a/chromium/ipc/ipc_channel_proxy.h b/chromium/ipc/ipc_channel_proxy.h index 779f2f9c934..a333a26c1ac 100644 --- a/chromium/ipc/ipc_channel_proxy.h +++ b/chromium/ipc/ipc_channel_proxy.h @@ -259,6 +259,10 @@ class IPC_EXPORT ChannelProxy : public Sender { return ipc_task_runner_; } + scoped_refptr<base::SingleThreadTaskRunner> listener_task_runner() { + return listener_task_runner_; + } + // Dispatches a message on the listener thread. void OnDispatchMessage(const Message& message); diff --git a/chromium/ipc/ipc_message.h b/chromium/ipc/ipc_message.h index 8a924e21952..d1ea54e1dfd 100644 --- a/chromium/ipc/ipc_message.h +++ b/chromium/ipc/ipc_message.h @@ -72,6 +72,8 @@ class IPC_MESSAGE_SUPPORT_EXPORT Message : public base::Pickle { Message(const Message& other); Message& operator=(const Message& other); + bool IsValid() const { return header_size() == sizeof(Header) && header(); } + PriorityValue priority() const { return static_cast<PriorityValue>(header()->flags & PRIORITY_MASK); } diff --git a/chromium/ipc/ipc_message_pipe_reader.cc b/chromium/ipc/ipc_message_pipe_reader.cc index ebc18a3a943..4a8ca8f34fc 100644 --- a/chromium/ipc/ipc_message_pipe_reader.cc +++ b/chromium/ipc/ipc_message_pipe_reader.cc @@ -50,9 +50,9 @@ void MessagePipeReader::Close() { } bool MessagePipeReader::Send(std::unique_ptr<Message> message) { + CHECK(message->IsValid()); TRACE_EVENT_WITH_FLOW0(TRACE_DISABLED_BY_DEFAULT("ipc.flow"), - "MessagePipeReader::Send", - message->flags(), + "MessagePipeReader::Send", message->flags(), TRACE_EVENT_FLAG_FLOW_OUT); base::Optional<std::vector<mojo::native::SerializedHandlePtr>> handles; MojoResult result = MOJO_RESULT_OK; @@ -87,9 +87,16 @@ void MessagePipeReader::SetPeerPid(int32_t peer_pid) { void MessagePipeReader::Receive( base::span<const uint8_t> data, base::Optional<std::vector<mojo::native::SerializedHandlePtr>> handles) { - Message message( - data.empty() ? "" : reinterpret_cast<const char*>(data.data()), - static_cast<uint32_t>(data.size())); + if (data.empty()) { + delegate_->OnBrokenDataReceived(); + return; + } + Message message(reinterpret_cast<const char*>(data.data()), + static_cast<uint32_t>(data.size())); + if (!message.IsValid()) { + delegate_->OnBrokenDataReceived(); + return; + } DVLOG(4) << "Receive " << message.type() << ": " << message.size(); MojoResult write_result = diff --git a/chromium/ipc/ipc_message_pipe_reader.h b/chromium/ipc/ipc_message_pipe_reader.h index a155dcfb372..a609f6c0603 100644 --- a/chromium/ipc/ipc_message_pipe_reader.h +++ b/chromium/ipc/ipc_message_pipe_reader.h @@ -49,6 +49,7 @@ class IPC_EXPORT MessagePipeReader : public mojom::Channel { public: virtual void OnPeerPidReceived(int32_t peer_pid) = 0; virtual void OnMessageReceived(const Message& message) = 0; + virtual void OnBrokenDataReceived() = 0; virtual void OnPipeError() = 0; virtual void OnAssociatedInterfaceRequest( const std::string& name, diff --git a/chromium/ipc/ipc_message_start.h b/chromium/ipc/ipc_message_start.h index 74256f04cc1..e24a858ed0b 100644 --- a/chromium/ipc/ipc_message_start.h +++ b/chromium/ipc/ipc_message_start.h @@ -18,7 +18,6 @@ enum IPCMessageStart { ViewMsgStart, InputMsgStart, TestMsgStart, - DevToolsMsgStart, WorkerMsgStart, NaClMsgStart, GpuChannelMsgStart, @@ -31,10 +30,7 @@ enum IPCMessageStart { P2PMsgStart, ResourceMsgStart, FileSystemMsgStart, - ChildProcessMsgStart, - ClipboardMsgStart, BlobMsgStart, - AppCacheMsgStart, AudioMsgStart, MidiMsgStart, ChromeMsgStart, @@ -42,7 +38,6 @@ enum IPCMessageStart { PrintMsgStart, SpellCheckMsgStart, ExtensionMsgStart, - QuotaMsgStart, TextInputClientMsgStart, JavaBridgeMsgStart, ShellMsgStart, diff --git a/chromium/ipc/ipc_message_utils.cc b/chromium/ipc/ipc_message_utils.cc index c8dc9fc39fb..a18b60d5062 100644 --- a/chromium/ipc/ipc_message_utils.cc +++ b/chromium/ipc/ipc_message_utils.cc @@ -332,34 +332,34 @@ bool ParamTraits<unsigned short>::Read(const base::Pickle* m, } void ParamTraits<unsigned short>::Log(const param_type& p, std::string* l) { - l->append(base::UintToString(p)); + l->append(base::NumberToString(p)); } void ParamTraits<int>::Log(const param_type& p, std::string* l) { - l->append(base::IntToString(p)); + l->append(base::NumberToString(p)); } void ParamTraits<unsigned int>::Log(const param_type& p, std::string* l) { - l->append(base::UintToString(p)); + l->append(base::NumberToString(p)); } #if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_FUCHSIA) || \ (defined(OS_ANDROID) && defined(ARCH_CPU_64_BITS)) void ParamTraits<long>::Log(const param_type& p, std::string* l) { - l->append(base::Int64ToString(static_cast<int64_t>(p))); + l->append(base::NumberToString(p)); } void ParamTraits<unsigned long>::Log(const param_type& p, std::string* l) { - l->append(base::Uint64ToString(static_cast<uint64_t>(p))); + l->append(base::NumberToString(p)); } #endif void ParamTraits<long long>::Log(const param_type& p, std::string* l) { - l->append(base::Int64ToString(static_cast<int64_t>(p))); + l->append(base::NumberToString(p)); } void ParamTraits<unsigned long long>::Log(const param_type& p, std::string* l) { - l->append(base::Uint64ToString(p)); + l->append(base::NumberToString(p)); } void ParamTraits<float>::Log(const param_type& p, std::string* l) { diff --git a/chromium/ipc/ipc_mojo_bootstrap_unittest.cc b/chromium/ipc/ipc_mojo_bootstrap_unittest.cc index 7bfd77c397f..46dca0efd0e 100644 --- a/chromium/ipc/ipc_mojo_bootstrap_unittest.cc +++ b/chromium/ipc/ipc_mojo_bootstrap_unittest.cc @@ -29,12 +29,43 @@ namespace { constexpr int32_t kTestServerPid = 42; constexpr int32_t kTestClientPid = 4242; +class Connection { + public: + explicit Connection(std::unique_ptr<IPC::MojoBootstrap> bootstrap, + int32_t sender_id) + : bootstrap_(std::move(bootstrap)) { + bootstrap_->Connect(&sender_, &receiver_); + sender_->SetPeerPid(sender_id); + } + + void TakeReceiver(IPC::mojom::ChannelAssociatedRequest* receiver) { + *receiver = std::move(receiver_); + } + + IPC::mojom::ChannelAssociatedPtr& GetSender() { return sender_; } + + private: + IPC::mojom::ChannelAssociatedPtr sender_; + IPC::mojom::ChannelAssociatedRequest receiver_; + std::unique_ptr<IPC::MojoBootstrap> bootstrap_; +}; + class PeerPidReceiver : public IPC::mojom::Channel { public: - PeerPidReceiver(IPC::mojom::ChannelAssociatedRequest request, - const base::Closure& on_peer_pid_set) - : binding_(this, std::move(request)), on_peer_pid_set_(on_peer_pid_set) {} - ~PeerPidReceiver() override = default; + enum class MessageExpectation { + kNotExpected, + kExpectedValid, + kExptectedInvalid + }; + + PeerPidReceiver( + IPC::mojom::ChannelAssociatedRequest request, + const base::Closure& on_peer_pid_set, + MessageExpectation message_expectation = MessageExpectation::kNotExpected) + : binding_(this, std::move(request)), + on_peer_pid_set_(on_peer_pid_set), + message_expectation_(message_expectation) {} + ~PeerPidReceiver() override {} // mojom::Channel: void SetPeerPid(int32_t pid) override { @@ -44,7 +75,15 @@ class PeerPidReceiver : public IPC::mojom::Channel { void Receive(base::span<const uint8_t> data, base::Optional<std::vector<mojo::native::SerializedHandlePtr>> - handles) override {} + handles) override { + ASSERT_NE(MessageExpectation::kNotExpected, message_expectation_); + + IPC::Message message(reinterpret_cast<const char*>(data.data()), + static_cast<uint32_t>(data.size())); + bool expected_valid = + message_expectation_ == MessageExpectation::kExpectedValid; + EXPECT_EQ(expected_valid, message.IsValid()); + } void GetAssociatedInterface( const std::string& name, @@ -55,6 +94,7 @@ class PeerPidReceiver : public IPC::mojom::Channel { private: mojo::AssociatedBinding<IPC::mojom::Channel> binding_; const base::Closure on_peer_pid_set_; + MessageExpectation message_expectation_; int32_t peer_pid_ = -1; DISALLOW_COPY_AND_ASSIGN(PeerPidReceiver); @@ -67,15 +107,15 @@ class IPCMojoBootstrapTest : public testing::Test { TEST_F(IPCMojoBootstrapTest, Connect) { base::MessageLoop message_loop; - std::unique_ptr<IPC::MojoBootstrap> bootstrap = IPC::MojoBootstrap::Create( - helper_.StartChild("IPCMojoBootstrapTestClient"), - IPC::Channel::MODE_SERVER, base::ThreadTaskRunnerHandle::Get(), - base::ThreadTaskRunnerHandle::Get()); + Connection connection( + IPC::MojoBootstrap::Create( + helper_.StartChild("IPCMojoBootstrapTestClient"), + IPC::Channel::MODE_SERVER, base::ThreadTaskRunnerHandle::Get(), + base::ThreadTaskRunnerHandle::Get()), + kTestServerPid); - IPC::mojom::ChannelAssociatedPtr sender; IPC::mojom::ChannelAssociatedRequest receiver; - bootstrap->Connect(&sender, &receiver); - sender->SetPeerPid(kTestServerPid); + connection.TakeReceiver(&receiver); base::RunLoop run_loop; PeerPidReceiver impl(std::move(receiver), run_loop.QuitClosure()); @@ -86,20 +126,40 @@ TEST_F(IPCMojoBootstrapTest, Connect) { EXPECT_TRUE(helper_.WaitForChildTestShutdown()); } +TEST_F(IPCMojoBootstrapTest, ReceiveEmptyMessage) { + base::MessageLoop message_loop; + Connection connection( + IPC::MojoBootstrap::Create( + helper_.StartChild("IPCMojoBootstrapTestEmptyMessage"), + IPC::Channel::MODE_SERVER, base::ThreadTaskRunnerHandle::Get(), + base::ThreadTaskRunnerHandle::Get()), + kTestServerPid); + + IPC::mojom::ChannelAssociatedRequest receiver; + connection.TakeReceiver(&receiver); + + base::RunLoop run_loop; + PeerPidReceiver impl(std::move(receiver), run_loop.QuitClosure(), + PeerPidReceiver::MessageExpectation::kExptectedInvalid); + run_loop.Run(); + + EXPECT_TRUE(helper_.WaitForChildTestShutdown()); +} + // A long running process that connects to us. MULTIPROCESS_TEST_MAIN_WITH_SETUP( IPCMojoBootstrapTestClientTestChildMain, ::mojo::edk::test::MultiprocessTestHelper::ChildSetup) { base::MessageLoop message_loop; - std::unique_ptr<IPC::MojoBootstrap> bootstrap = IPC::MojoBootstrap::Create( - std::move(mojo::edk::test::MultiprocessTestHelper::primordial_pipe), - IPC::Channel::MODE_CLIENT, base::ThreadTaskRunnerHandle::Get(), - base::ThreadTaskRunnerHandle::Get()); + Connection connection( + IPC::MojoBootstrap::Create( + std::move(mojo::edk::test::MultiprocessTestHelper::primordial_pipe), + IPC::Channel::MODE_CLIENT, base::ThreadTaskRunnerHandle::Get(), + base::ThreadTaskRunnerHandle::Get()), + kTestClientPid); - IPC::mojom::ChannelAssociatedPtr sender; IPC::mojom::ChannelAssociatedRequest receiver; - bootstrap->Connect(&sender, &receiver); - sender->SetPeerPid(kTestClientPid); + connection.TakeReceiver(&receiver); base::RunLoop run_loop; PeerPidReceiver impl(std::move(receiver), run_loop.QuitClosure()); @@ -110,4 +170,30 @@ MULTIPROCESS_TEST_MAIN_WITH_SETUP( return 0; } +// A long running process that connects to us. +MULTIPROCESS_TEST_MAIN_WITH_SETUP( + IPCMojoBootstrapTestEmptyMessageTestChildMain, + ::mojo::edk::test::MultiprocessTestHelper::ChildSetup) { + base::MessageLoop message_loop; + Connection connection( + IPC::MojoBootstrap::Create( + std::move(mojo::edk::test::MultiprocessTestHelper::primordial_pipe), + IPC::Channel::MODE_CLIENT, base::ThreadTaskRunnerHandle::Get(), + base::ThreadTaskRunnerHandle::Get()), + kTestClientPid); + + IPC::mojom::ChannelAssociatedRequest receiver; + connection.TakeReceiver(&receiver); + auto& sender = connection.GetSender(); + + uint8_t data = 0; + sender->Receive(base::make_span(&data, 0), {}); + + base::RunLoop run_loop; + PeerPidReceiver impl(std::move(receiver), run_loop.QuitClosure()); + run_loop.Run(); + + return 0; +} + } // namespace diff --git a/chromium/ipc/ipc_platform_file.cc b/chromium/ipc/ipc_platform_file.cc index 72ed737b6a8..d8108b3c799 100644 --- a/chromium/ipc/ipc_platform_file.cc +++ b/chromium/ipc/ipc_platform_file.cc @@ -9,6 +9,8 @@ #include <unistd.h> #include "base/posix/eintr_wrapper.h" +#elif defined(OS_WIN) +#include <windows.h> #endif namespace IPC { diff --git a/chromium/ipc/ipc_sync_channel.cc b/chromium/ipc/ipc_sync_channel.cc index 146feb0c498..c4f14dce5cf 100644 --- a/chromium/ipc/ipc_sync_channel.cc +++ b/chromium/ipc/ipc_sync_channel.cc @@ -84,14 +84,16 @@ class SyncChannel::ReceivedSyncMsgQueue : class NestedSendDoneWatcher { public: NestedSendDoneWatcher(SyncChannel::SyncContext* context, - base::RunLoop* run_loop) + base::RunLoop* run_loop, + scoped_refptr<base::SequencedTaskRunner> task_runner) : sync_msg_queue_(context->received_sync_msgs()), outer_state_(sync_msg_queue_->top_send_done_event_watcher_), event_(context->GetSendDoneEvent()), callback_( base::BindOnce(&SyncChannel::SyncContext::OnSendDoneEventSignaled, context, - run_loop)) { + run_loop)), + task_runner_(std::move(task_runner)) { sync_msg_queue_->top_send_done_event_watcher_ = this; if (outer_state_) outer_state_->StopWatching(); @@ -111,8 +113,10 @@ class SyncChannel::ReceivedSyncMsgQueue : } void StartWatching() { - watcher_.StartWatching(event_, base::BindOnce(&NestedSendDoneWatcher::Run, - base::Unretained(this))); + watcher_.StartWatching( + event_, + base::BindOnce(&NestedSendDoneWatcher::Run, base::Unretained(this)), + task_runner_); } void StopWatching() { watcher_.StopWatching(); } @@ -123,6 +127,7 @@ class SyncChannel::ReceivedSyncMsgQueue : base::WaitableEvent* const event_; base::WaitableEventWatcher::EventCallback callback_; base::WaitableEventWatcher watcher_; + scoped_refptr<base::SequencedTaskRunner> task_runner_; DISALLOW_COPY_AND_ASSIGN(NestedSendDoneWatcher); }; @@ -206,9 +211,10 @@ class SyncChannel::ReceivedSyncMsgQueue : } for (; it != message_queue_.end(); it++) { int message_group = it->context->restrict_dispatch_group(); - if (!dispatching_context || - message_group == kRestrictDispatchGroup_None || - message_group == dispatching_context->restrict_dispatch_group()) { + if (message_group == kRestrictDispatchGroup_None || + (dispatching_context && + message_group == + dispatching_context->restrict_dispatch_group())) { message = it->message; context = it->context; it = message_queue_.erase(it); @@ -492,7 +498,8 @@ void SyncChannel::SyncContext::OnChannelOpened() { shutdown_watcher_.StartWatching( shutdown_event_, base::Bind(&SyncChannel::SyncContext::OnShutdownEventSignaled, - base::Unretained(this))); + base::Unretained(this)), + ipc_task_runner()); Context::OnChannelOpened(); } @@ -689,7 +696,8 @@ void SyncChannel::WaitForReply(mojo::SyncHandleRegistry* registry, void SyncChannel::WaitForReplyWithNestedMessageLoop(SyncContext* context) { base::RunLoop nested_loop(base::RunLoop::Type::kNestableTasksAllowed); - ReceivedSyncMsgQueue::NestedSendDoneWatcher watcher(context, &nested_loop); + ReceivedSyncMsgQueue::NestedSendDoneWatcher watcher( + context, &nested_loop, context->listener_task_runner()); nested_loop.Run(); } @@ -710,8 +718,9 @@ void SyncChannel::StartWatching() { // immediately if woken up by a message which it's allowed to dispatch. dispatch_watcher_.StartWatching( sync_context()->GetDispatchEvent(), - base::Bind(&SyncChannel::OnDispatchEventSignaled, - base::Unretained(this))); + base::BindOnce(&SyncChannel::OnDispatchEventSignaled, + base::Unretained(this)), + sync_context()->listener_task_runner()); } void SyncChannel::OnChannelInit() { diff --git a/chromium/ipc/ipc_sync_message.h b/chromium/ipc/ipc_sync_message.h index c9a1287a66d..cfac2ded124 100644 --- a/chromium/ipc/ipc_sync_message.h +++ b/chromium/ipc/ipc_sync_message.h @@ -8,7 +8,7 @@ #include <stdint.h> #if defined(OS_WIN) -#include <windows.h> +#include "base/win/windows_types.h" #endif #include <memory> |