diff --git a/components/nacl/loader/nacl_listener.cc b/components/nacl/loader/nacl_listener.cc index c67e5bcae5e426..98444678e2869d 100644 --- a/components/nacl/loader/nacl_listener.cc +++ b/components/nacl/loader/nacl_listener.cc @@ -225,10 +225,10 @@ void NaClListener::Listen() { &shutdown_event_); filter_ = channel_->CreateSyncMessageFilter(); channel_->AddFilter(new FileTokenMessageFilter()); - channel_->Init(channel_name, IPC::Channel::MODE_CLIENT, true); IPC::AttachmentBroker* global = IPC::AttachmentBroker::GetGlobal(); if (global && !global->IsPrivilegedBroker()) global->RegisterBrokerCommunicationChannel(channel_.get()); + channel_->Init(channel_name, IPC::Channel::MODE_CLIENT, true); main_loop_ = base::MessageLoop::current(); main_loop_->Run(); } diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 4b16440bcf874a..4061947e26511f 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc @@ -723,11 +723,6 @@ bool RenderProcessHostImpl::Init() { const std::string channel_id = IPC::Channel::GenerateVerifiedChannelID(std::string()); channel_ = CreateChannelProxy(channel_id); -#if USE_ATTACHMENT_BROKER - IPC::AttachmentBroker::GetGlobal()->RegisterCommunicationChannel( - channel_.get(), content::BrowserThread::GetMessageLoopProxyForThread( - content::BrowserThread::IO)); -#endif // Call the embedder first so that their IPC filters have priority. GetContentClient()->browser()->RenderProcessWillLaunch(this); @@ -823,9 +818,15 @@ std::unique_ptr RenderProcessHostImpl::CreateChannelProxy( } #endif // OS_ANDROID - return IPC::ChannelProxy::Create( - IPC::ChannelMojo::CreateServerFactory(std::move(handle)), this, - runner.get()); + std::unique_ptr channel( + new IPC::ChannelProxy(this, runner.get())); +#if USE_ATTACHMENT_BROKER + IPC::AttachmentBroker::GetGlobal()->RegisterCommunicationChannel( + channel.get(), content::BrowserThread::GetMessageLoopProxyForThread( + content::BrowserThread::IO)); +#endif + channel->Init(IPC::ChannelMojo::CreateServerFactory(std::move(handle)), true); + return channel; } // Do NOT expand ifdef or run time condition checks here! See comment above. @@ -836,8 +837,15 @@ std::unique_ptr RenderProcessHostImpl::CreateChannelProxy( } #endif // OS_ANDROID - return IPC::ChannelProxy::Create(channel_id, IPC::Channel::MODE_SERVER, this, - runner.get()); + std::unique_ptr channel( + new IPC::ChannelProxy(this, runner.get())); +#if USE_ATTACHMENT_BROKER + IPC::AttachmentBroker::GetGlobal()->RegisterCommunicationChannel( + channel.get(), content::BrowserThread::GetMessageLoopProxyForThread( + content::BrowserThread::IO)); +#endif + channel->Init(channel_id, IPC::Channel::MODE_SERVER, true); + return channel; } void RenderProcessHostImpl::CreateMessageFilters() { diff --git a/content/child/child_thread_impl.cc b/content/child/child_thread_impl.cc index d3f45dfc80278b..b7aa75e4f8fb60 100644 --- a/content/child/child_thread_impl.cc +++ b/content/child/child_thread_impl.cc @@ -472,10 +472,10 @@ void ChildThreadImpl::Init(const Options& options) { channel_->AddFilter(startup_filter); } - ConnectChannel(options.use_mojo_channel, options.in_process_ipc_token); IPC::AttachmentBroker* broker = IPC::AttachmentBroker::GetGlobal(); if (broker && !broker->IsPrivilegedBroker()) broker->RegisterBrokerCommunicationChannel(channel_.get()); + ConnectChannel(options.use_mojo_channel, options.in_process_ipc_token); int connection_timeout = kConnectionTimeoutS; std::string connection_override = diff --git a/content/common/child_process_host_impl.cc b/content/common/child_process_host_impl.cc index e9b81e75f9d894..1aa93b529873b9 100644 --- a/content/common/child_process_host_impl.cc +++ b/content/common/child_process_host_impl.cc @@ -133,12 +133,17 @@ void ChildProcessHostImpl::ForceShutdown() { std::string ChildProcessHostImpl::CreateChannel() { channel_id_ = IPC::Channel::GenerateVerifiedChannelID(std::string()); channel_ = IPC::Channel::CreateServer(channel_id_, this); - if (!channel_->Connect()) - return std::string(); #if USE_ATTACHMENT_BROKER IPC::AttachmentBroker::GetGlobal()->RegisterCommunicationChannel( channel_.get(), base::MessageLoopForIO::current()->task_runner()); #endif + if (!channel_->Connect()) { +#if USE_ATTACHMENT_BROKER + IPC::AttachmentBroker::GetGlobal()->DeregisterCommunicationChannel( + channel_.get()); +#endif + return std::string(); + } for (size_t i = 0; i < filters_.size(); ++i) filters_[i]->OnFilterAdded(channel_.get()); diff --git a/ipc/attachment_broker_mac_unittest.cc b/ipc/attachment_broker_mac_unittest.cc index d30e8a75732ead..3be3d4397d6a49 100644 --- a/ipc/attachment_broker_mac_unittest.cc +++ b/ipc/attachment_broker_mac_unittest.cc @@ -423,6 +423,12 @@ class IPCAttachmentBrokerMacTest : public IPCTestBase { // Setup shared between tests. void CommonSetUp(const char* name) { + PreConnectSetUp(name); + PostConnectSetUp(); + } + + // All of setup before the channel is connected. + void PreConnectSetUp(const char* name) { Init(name); MachPreForkSetUp(); @@ -432,6 +438,10 @@ class IPCAttachmentBrokerMacTest : public IPCTestBase { broker_->AddObserver(&observer_, task_runner()); CreateChannel(&proxy_listener_); broker_->RegisterBrokerCommunicationChannel(channel()); + } + + // All of setup including the connection and everything after. + void PostConnectSetUp() { ASSERT_TRUE(ConnectChannel()); ASSERT_TRUE(StartClient()); @@ -871,11 +881,11 @@ MULTIPROCESS_IPC_TEST_CLIENT_MAIN(SendPosixFDAndMachPort) { // process sending an attachment to another unprivileged process. TEST_F(IPCAttachmentBrokerMacTest, SendSharedMemoryHandleToSelf) { SetBroker(new MockBroker); - CommonSetUp("SendSharedMemoryHandleToSelf"); - + PreConnectSetUp("SendSharedMemoryHandleToSelf"); // Technically, the channel is an endpoint, but we need the proxy listener to // receive the messages so that it can quit the message loop. channel()->SetAttachmentBrokerEndpoint(false); + PostConnectSetUp(); get_proxy_listener()->set_listener(get_broker()); { @@ -940,8 +950,12 @@ TEST_F(IPCAttachmentBrokerMacTest, SendSharedMemoryHandleChannelProxy) { options.message_loop_type = base::MessageLoop::TYPE_IO; thread->StartWithOptions(options); - CreateChannelProxy(get_proxy_listener(), thread->task_runner().get()); + set_channel_proxy(std::unique_ptr(new IPC::ChannelProxy( + get_proxy_listener(), thread->task_runner().get()))); get_broker()->RegisterBrokerCommunicationChannel(channel_proxy()); + channel_proxy()->Init( + CreateChannelFactory(GetTestChannelHandle(), thread->task_runner().get()), + true); ASSERT_TRUE(StartClient()); @@ -1060,11 +1074,11 @@ MULTIPROCESS_IPC_TEST_CLIENT_MAIN(ShareReadOnlyToProcess) { // not have the task port for the parent process. TEST_F(IPCAttachmentBrokerMacTest, SendSharedMemoryHandleToSelfDelayedPort) { SetBroker(new MockBroker); - CommonSetUp("SendSharedMemoryHandleToSelfDelayedPort"); - + PreConnectSetUp("SendSharedMemoryHandleToSelfDelayedPort"); // Technically, the channel is an endpoint, but we need the proxy listener to // receive the messages so that it can quit the message loop. channel()->SetAttachmentBrokerEndpoint(false); + PostConnectSetUp(); get_proxy_listener()->set_listener(get_broker()); { diff --git a/ipc/attachment_broker_privileged_win_unittest.cc b/ipc/attachment_broker_privileged_win_unittest.cc index dc3bffc14e05db..3c8df8e806468a 100644 --- a/ipc/attachment_broker_privileged_win_unittest.cc +++ b/ipc/attachment_broker_privileged_win_unittest.cc @@ -265,11 +265,21 @@ class IPCAttachmentBrokerPrivilegedWinTest : public IPCTestBase { } void CommonSetUp() { + PreConnectSetUp(); + PostConnectSetUp(); + } + + // All of setup before the channel is connected. + void PreConnectSetUp() { if (!broker_.get()) set_broker(new IPC::AttachmentBrokerUnprivilegedWin); broker_->AddObserver(&observer_, task_runner()); CreateChannel(&proxy_listener_); broker_->RegisterBrokerCommunicationChannel(channel()); + } + + // All of setup including the connection and everything after. + void PostConnectSetUp() { ASSERT_TRUE(ConnectChannel()); ASSERT_TRUE(StartClient()); @@ -390,10 +400,12 @@ TEST_F(IPCAttachmentBrokerPrivilegedWinTest, SendHandleToSelf) { Init("SendHandleToSelf"); set_broker(new MockBroker); - CommonSetUp(); + + PreConnectSetUp(); // Technically, the channel is an endpoint, but we need the proxy listener to // receive the messages so that it can quit the message loop. channel()->SetAttachmentBrokerEndpoint(false); + PostConnectSetUp(); get_proxy_listener()->set_listener(get_broker()); HANDLE h = CreateTempFile(); diff --git a/ipc/ipc_channel.h b/ipc/ipc_channel.h index dba2150410cd2c..fdd0b352964a4a 100644 --- a/ipc/ipc_channel.h +++ b/ipc/ipc_channel.h @@ -166,6 +166,9 @@ class IPC_EXPORT Channel : public Endpoint { // connect to a pre-existing pipe. Note, calling Connect() // will not block the calling thread and may complete // asynchronously. + // + // The subclass implementation must call WillConnect() at the beginning of its + // implementation. virtual bool Connect() WARN_UNUSED_RESULT = 0; // Close this Channel explicitly. May be called multiple times. @@ -256,6 +259,16 @@ class IPC_EXPORT Channel : public Endpoint { void* buffer_; size_t length_; }; + + // Endpoint overrides. + void OnSetAttachmentBrokerEndpoint() override; + + // Subclasses must call this method at the beginning of their implementation + // of Connect(). + void WillConnect(); + + private: + bool did_start_connect_ = false; }; #if defined(OS_POSIX) diff --git a/ipc/ipc_channel_common.cc b/ipc/ipc_channel_common.cc index d999733fb0d470..b5dcb1ab4bf933 100644 --- a/ipc/ipc_channel_common.cc +++ b/ipc/ipc_channel_common.cc @@ -52,5 +52,13 @@ bool Channel::IsSendThreadSafe() const { return false; } +void Channel::OnSetAttachmentBrokerEndpoint() { + CHECK(!did_start_connect_); +} + +void Channel::WillConnect() { + did_start_connect_ = true; +} + } // namespace IPC diff --git a/ipc/ipc_channel_nacl.cc b/ipc/ipc_channel_nacl.cc index 197e5993895b0a..008b50c6864ede 100644 --- a/ipc/ipc_channel_nacl.cc +++ b/ipc/ipc_channel_nacl.cc @@ -155,6 +155,8 @@ base::ProcessId ChannelNacl::GetSelfPID() const { } bool ChannelNacl::Connect() { + WillConnect(); + if (pipe_ == -1) { DLOG(WARNING) << "Channel creation failed: " << pipe_name_; return false; diff --git a/ipc/ipc_channel_posix.cc b/ipc/ipc_channel_posix.cc index 42db9e1a17f195..fffbd2b3e2d9f0 100644 --- a/ipc/ipc_channel_posix.cc +++ b/ipc/ipc_channel_posix.cc @@ -341,6 +341,8 @@ bool ChannelPosix::CreatePipe( } bool ChannelPosix::Connect() { + WillConnect(); + if (!server_listen_pipe_.is_valid() && !pipe_.is_valid()) { DLOG(WARNING) << "Channel creation failed: " << pipe_name_; return false; diff --git a/ipc/ipc_channel_proxy.cc b/ipc/ipc_channel_proxy.cc index f0031d6f77d684..9af174bf8e30e1 100644 --- a/ipc/ipc_channel_proxy.cc +++ b/ipc/ipc_channel_proxy.cc @@ -490,6 +490,7 @@ base::ProcessId ChannelProxy::GetPeerPID() const { } void ChannelProxy::OnSetAttachmentBrokerEndpoint() { + CHECK(!did_init_); context()->set_attachment_broker_endpoint(is_attachment_broker_endpoint()); } diff --git a/ipc/ipc_channel_proxy.h b/ipc/ipc_channel_proxy.h index 2c5ec98e43a8a6..0c9323304098c2 100644 --- a/ipc/ipc_channel_proxy.h +++ b/ipc/ipc_channel_proxy.h @@ -97,6 +97,11 @@ class IPC_EXPORT ChannelProxy : public Endpoint, public base::NonThreadSafe { Listener* listener, const scoped_refptr& ipc_task_runner); + // Constructs a ChannelProxy without initializing it. + ChannelProxy( + Listener* listener, + const scoped_refptr& ipc_task_runner); + ~ChannelProxy() override; // Initializes the channel proxy. Only call this once to initialize a channel @@ -159,9 +164,6 @@ class IPC_EXPORT ChannelProxy : public Endpoint, public base::NonThreadSafe { // to the internal state. ChannelProxy(Context* context); - ChannelProxy( - Listener* listener, - const scoped_refptr& ipc_task_runner); // Used internally to hold state that is referenced on the IPC thread. class Context : public base::RefCountedThreadSafe, diff --git a/ipc/ipc_channel_win.cc b/ipc/ipc_channel_win.cc index 6ae83b77f9261d..404e688a212367 100644 --- a/ipc/ipc_channel_win.cc +++ b/ipc/ipc_channel_win.cc @@ -392,6 +392,8 @@ bool ChannelWin::CreatePipe(const IPC::ChannelHandle &channel_handle, } bool ChannelWin::Connect() { + WillConnect(); + DLOG_IF(WARNING, thread_check_.get()) << "Connect called more than once"; if (!thread_check_.get()) diff --git a/ipc/ipc_endpoint.h b/ipc/ipc_endpoint.h index 2ace1fe999c946..3315f54e8a62a9 100644 --- a/ipc/ipc_endpoint.h +++ b/ipc/ipc_endpoint.h @@ -32,7 +32,7 @@ class IPC_EXPORT Endpoint : public Sender { // A callback that indicates that is_attachment_broker_endpoint() has been // changed. - virtual void OnSetAttachmentBrokerEndpoint(){}; + virtual void OnSetAttachmentBrokerEndpoint() = 0; // Whether this channel is used as an endpoint for sending and receiving // brokerable attachment messages to/from the broker process. diff --git a/ipc/ipc_test_base.h b/ipc/ipc_test_base.h index 5637a57e8906a1..c85c74f43a19e4 100644 --- a/ipc/ipc_test_base.h +++ b/ipc/ipc_test_base.h @@ -105,6 +105,10 @@ class IPCTestBase : public base::MultiProcessTest { IPC::Channel* channel() { return channel_.get(); } IPC::ChannelProxy* channel_proxy() { return channel_proxy_.get(); } + void set_channel_proxy(std::unique_ptr proxy) { + DCHECK(!channel_proxy_); + channel_proxy_.swap(proxy); + } const base::Process& client_process() const { return client_process_; } scoped_refptr task_runner(); diff --git a/ipc/mojo/ipc_channel_mojo.cc b/ipc/mojo/ipc_channel_mojo.cc index 8806c6a4136b02..1f05d268f18864 100644 --- a/ipc/mojo/ipc_channel_mojo.cc +++ b/ipc/mojo/ipc_channel_mojo.cc @@ -239,6 +239,7 @@ ChannelMojo::~ChannelMojo() { } bool ChannelMojo::Connect() { + WillConnect(); base::AutoLock lock(lock_); DCHECK(!task_runner_); task_runner_ = base::ThreadTaskRunnerHandle::Get(); diff --git a/remoting/host/desktop_process.cc b/remoting/host/desktop_process.cc index ca03a105bdb03c..525e1f66bb73b5 100644 --- a/remoting/host/desktop_process.cc +++ b/remoting/host/desktop_process.cc @@ -140,14 +140,12 @@ bool DesktopProcess::Start( } // Connect to the daemon. - daemon_channel_ = - IPC::ChannelProxy::Create(daemon_channel_name_, IPC::Channel::MODE_CLIENT, - this, io_task_runner.get()); - + daemon_channel_.reset(new IPC::ChannelProxy(this, io_task_runner.get())); IPC::AttachmentBrokerUnprivileged::CreateBrokerIfNeeded(); IPC::AttachmentBroker* broker = IPC::AttachmentBroker::GetGlobal(); if (broker && !broker->IsPrivilegedBroker()) broker->RegisterBrokerCommunicationChannel(daemon_channel_.get()); + daemon_channel_->Init(daemon_channel_name_, IPC::Channel::MODE_CLIENT, true); // Pass |desktop_pipe| to the daemon. daemon_channel_->Send( diff --git a/remoting/host/desktop_session_agent.cc b/remoting/host/desktop_session_agent.cc index 26ee9e1a9d9875..064845c969e608 100644 --- a/remoting/host/desktop_session_agent.cc +++ b/remoting/host/desktop_session_agent.cc @@ -13,6 +13,7 @@ #include "base/memory/shared_memory.h" #include "base/process/process_handle.h" #include "build/build_config.h" +#include "ipc/attachment_broker.h" #include "ipc/ipc_channel_proxy.h" #include "ipc/ipc_message.h" #include "ipc/ipc_message_macros.h" @@ -215,6 +216,10 @@ void DesktopSessionAgent::OnChannelError() { DCHECK(caller_task_runner_->BelongsToCurrentThread()); // Make sure the channel is closed. + if (IPC::AttachmentBroker::GetGlobal()) { + IPC::AttachmentBroker::GetGlobal()->DeregisterCommunicationChannel( + network_channel_.get()); + } network_channel_.reset(); desktop_pipe_.Close(); @@ -413,6 +418,10 @@ void DesktopSessionAgent::Stop() { delegate_.reset(); // Make sure the channel is closed. + if (IPC::AttachmentBroker::GetGlobal()) { + IPC::AttachmentBroker::GetGlobal()->DeregisterCommunicationChannel( + network_channel_.get()); + } network_channel_.reset(); if (started_) { diff --git a/remoting/host/ipc_util.h b/remoting/host/ipc_util.h index 5642be19ed6f7e..2d444d7f016444 100644 --- a/remoting/host/ipc_util.h +++ b/remoting/host/ipc_util.h @@ -34,6 +34,7 @@ namespace remoting { // on the caller's thread while using |io_task_runner| to send and receive // messages in the background. The client end is returned as a pipe handle // (inheritable on Windows). +// The channel is registered with the global AttachmentBroker. bool CreateConnectedIpcChannel( scoped_refptr io_task_runner, IPC::Listener* listener, diff --git a/remoting/host/ipc_util_posix.cc b/remoting/host/ipc_util_posix.cc index 3747c1dad3ca0d..54aa5bff5fb073 100644 --- a/remoting/host/ipc_util_posix.cc +++ b/remoting/host/ipc_util_posix.cc @@ -13,6 +13,7 @@ #include "base/logging.h" #include "base/posix/eintr_wrapper.h" #include "base/single_thread_task_runner.h" +#include "ipc/attachment_broker.h" #include "ipc/ipc_channel.h" #include "ipc/ipc_channel_proxy.h" @@ -45,10 +46,14 @@ bool CreateConnectedIpcChannel( // Wrap the pipe into an IPC channel. base::FileDescriptor fd(pipe_fds[0], false); - IPC::ChannelHandle handle(socket_name, fd); - *server_out = IPC::ChannelProxy::Create(IPC::ChannelHandle(socket_name, fd), - IPC::Channel::MODE_SERVER, listener, - io_task_runner.get()); + server_out->reset(new IPC::ChannelProxy(listener, io_task_runner)); + if (IPC::AttachmentBroker::GetGlobal()) { + IPC::AttachmentBroker::GetGlobal()->RegisterCommunicationChannel( + server_out->get(), io_task_runner); + } + (*server_out) + ->Init(IPC::ChannelHandle(socket_name, fd), IPC::Channel::MODE_SERVER, + true); *client_out = base::File(pipe_fds[1]); return true; diff --git a/remoting/host/ipc_util_win.cc b/remoting/host/ipc_util_win.cc index a7187a81805d8f..5da5f8264fe1fe 100644 --- a/remoting/host/ipc_util_win.cc +++ b/remoting/host/ipc_util_win.cc @@ -13,6 +13,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/win/scoped_handle.h" #include "base/win/win_util.h" +#include "ipc/attachment_broker.h" #include "ipc/ipc_channel.h" #include "ipc/ipc_channel_proxy.h" #include "remoting/host/win/security_descriptor.h" @@ -56,9 +57,12 @@ bool CreateConnectedIpcChannel( } // Wrap the pipe into an IPC channel. - std::unique_ptr server = IPC::ChannelProxy::Create( - IPC::ChannelHandle(pipe.Get()), IPC::Channel::MODE_SERVER, listener, - io_task_runner); + std::unique_ptr server( + new IPC::ChannelProxy(listener, io_task_runner)); + IPC::AttachmentBroker::GetGlobal()->RegisterCommunicationChannel( + server.get(), io_task_runner); + server->Init(IPC::ChannelHandle(pipe.Get()), IPC::Channel::MODE_SERVER, + true); // Convert the channel name to the pipe name. std::string pipe_name(kChromePipeNamePrefix); diff --git a/remoting/host/remoting_me2me_host.cc b/remoting/host/remoting_me2me_host.cc index a370b7fe9c205b..0c20c2f4baeff1 100644 --- a/remoting/host/remoting_me2me_host.cc +++ b/remoting/host/remoting_me2me_host.cc @@ -473,15 +473,13 @@ bool HostProcess::InitWithCommandLine(const base::CommandLine* cmd_line) { #endif // defined(OS_POSIX) // Connect to the daemon process. - daemon_channel_ = IPC::ChannelProxy::Create(channel_handle, - IPC::Channel::MODE_CLIENT, - this, - context_->network_task_runner()); - + daemon_channel_.reset( + new IPC::ChannelProxy(this, context_->network_task_runner())); IPC::AttachmentBrokerUnprivileged::CreateBrokerIfNeeded(); IPC::AttachmentBroker* broker = IPC::AttachmentBroker::GetGlobal(); if (broker && !broker->IsPrivilegedBroker()) broker->RegisterBrokerCommunicationChannel(daemon_channel_.get()); + daemon_channel_->Init(channel_handle, IPC::Channel::MODE_CLIENT, true); #else // !defined(REMOTING_MULTI_PROCESS) if (cmd_line->HasSwitch(kHostConfigSwitchName)) { diff --git a/remoting/host/win/unprivileged_process_delegate.cc b/remoting/host/win/unprivileged_process_delegate.cc index 66d6c1e7a82548..8203318ca4f873 100644 --- a/remoting/host/win/unprivileged_process_delegate.cc +++ b/remoting/host/win/unprivileged_process_delegate.cc @@ -337,8 +337,6 @@ void UnprivilegedProcessDelegate::LaunchProcess( } channel_ = std::move(server); - IPC::AttachmentBroker::GetGlobal()->RegisterCommunicationChannel( - channel_.get(), io_task_runner_); ReportProcessLaunched(std::move(worker_process)); } diff --git a/remoting/host/win/wts_session_process_delegate.cc b/remoting/host/win/wts_session_process_delegate.cc index be23baf3511300..779cc6274b36f1 100644 --- a/remoting/host/win/wts_session_process_delegate.cc +++ b/remoting/host/win/wts_session_process_delegate.cc @@ -382,9 +382,12 @@ void WtsSessionProcessDelegate::Core::DoLaunchProcess() { } // Wrap the pipe into an IPC channel. - std::unique_ptr channel(IPC::ChannelProxy::Create( - IPC::ChannelHandle(pipe.Get()), IPC::Channel::MODE_SERVER, this, - io_task_runner_)); + std::unique_ptr channel( + new IPC::ChannelProxy(this, io_task_runner_)); + IPC::AttachmentBroker::GetGlobal()->RegisterCommunicationChannel( + channel.get(), io_task_runner_); + channel->Init(IPC::ChannelHandle(pipe.Get()), IPC::Channel::MODE_SERVER, + true); // Pass the name of the IPC channel to use. command_line.AppendSwitchNative(kDaemonPipeSwitchName, @@ -424,9 +427,6 @@ void WtsSessionProcessDelegate::Core::DoLaunchProcess() { channel_ = std::move(channel); pipe_ = std::move(pipe); - IPC::AttachmentBroker::GetGlobal()->RegisterCommunicationChannel( - channel_.get(), io_task_runner_); - // Report success if the worker process is lauched directly. Otherwise, PID of // the client connected to the pipe will be used later. See // OnChannelConnected().