Chromium Code Reviews| Index: ipc/mojo/ipc_channel_mojo.cc |
| diff --git a/ipc/mojo/ipc_channel_mojo.cc b/ipc/mojo/ipc_channel_mojo.cc |
| index cff2789c710301fbb5a251a0ab4f2288a06e2777..9badfdf5d4b4461b0bbcdb4fe571bc3566bd6c88 100644 |
| --- a/ipc/mojo/ipc_channel_mojo.cc |
| +++ b/ipc/mojo/ipc_channel_mojo.cc |
| @@ -7,6 +7,7 @@ |
| #include "base/bind.h" |
| #include "base/bind_helpers.h" |
| #include "base/lazy_instance.h" |
| +#include "base/thread_task_runner_handle.h" |
| #include "ipc/ipc_listener.h" |
| #include "ipc/ipc_logging.h" |
| #include "ipc/ipc_message_attachment_set.h" |
| @@ -74,7 +75,10 @@ class ClientChannelMojo : public ChannelMojo, |
| const mojo::Callback<void(int32_t)>& callback) override; |
| private: |
| + void BindPipe(mojo::ScopedMessagePipeHandle handle); |
| + |
| mojo::Binding<ClientChannel> binding_; |
| + base::WeakPtrFactory<ClientChannelMojo> weak_factory_; |
| DISALLOW_COPY_AND_ASSIGN(ClientChannelMojo); |
| }; |
| @@ -84,7 +88,8 @@ ClientChannelMojo::ClientChannelMojo(ChannelMojo::Delegate* delegate, |
| const ChannelHandle& handle, |
| Listener* listener) |
| : ChannelMojo(delegate, io_runner, handle, Channel::MODE_CLIENT, listener), |
| - binding_(this) { |
| + binding_(this), |
| + weak_factory_(this) { |
| } |
| ClientChannelMojo::~ClientChannelMojo() { |
| @@ -92,7 +97,8 @@ ClientChannelMojo::~ClientChannelMojo() { |
| void ClientChannelMojo::OnPipeAvailable( |
| mojo::embedder::ScopedPlatformHandle handle) { |
| - binding_.Bind(CreateMessagingPipe(handle.Pass())); |
| + CreateMessagingPipe(handle.Pass(), base::Bind(&ClientChannelMojo::BindPipe, |
| + weak_factory_.GetWeakPtr())); |
| } |
| void ClientChannelMojo::OnConnectionError() { |
| @@ -107,6 +113,10 @@ void ClientChannelMojo::Init( |
| callback.Run(GetSelfPID()); |
| } |
| +void ClientChannelMojo::BindPipe(mojo::ScopedMessagePipeHandle handle) { |
| + binding_.Bind(handle.Pass()); |
| +} |
| + |
| //------------------------------------------------------------------------------ |
| class ServerChannelMojo : public ChannelMojo, public mojo::ErrorHandler { |
| @@ -125,11 +135,15 @@ class ServerChannelMojo : public ChannelMojo, public mojo::ErrorHandler { |
| void Close() override; |
| private: |
| + void InitClientChannel(mojo::ScopedMessagePipeHandle peer_handle, |
| + mojo::ScopedMessagePipeHandle handle); |
| + |
| // ClientChannelClient implementation |
| void ClientChannelWasInitialized(int32_t peer_pid); |
| mojo::InterfacePtr<ClientChannel> client_channel_; |
| mojo::ScopedMessagePipeHandle message_pipe_; |
| + base::WeakPtrFactory<ServerChannelMojo> weak_factory_; |
|
Hajime Morrita
2015/05/11 22:19:21
Having weak_factory_ for Channel is tricky but I b
|
| DISALLOW_COPY_AND_ASSIGN(ServerChannelMojo); |
| }; |
| @@ -138,7 +152,8 @@ ServerChannelMojo::ServerChannelMojo(ChannelMojo::Delegate* delegate, |
| scoped_refptr<base::TaskRunner> io_runner, |
| const ChannelHandle& handle, |
| Listener* listener) |
| - : ChannelMojo(delegate, io_runner, handle, Channel::MODE_SERVER, listener) { |
| + : ChannelMojo(delegate, io_runner, handle, Channel::MODE_SERVER, listener), |
| + weak_factory_(this) { |
| } |
| ServerChannelMojo::~ServerChannelMojo() { |
| @@ -155,14 +170,20 @@ void ServerChannelMojo::OnPipeAvailable( |
| listener()->OnChannelError(); |
| return; |
| } |
| + CreateMessagingPipe( |
| + handle.Pass(), |
| + base::Bind(&ServerChannelMojo::InitClientChannel, |
| + weak_factory_.GetWeakPtr(), base::Passed(&peer))); |
| +} |
| +void ServerChannelMojo::InitClientChannel( |
| + mojo::ScopedMessagePipeHandle peer_handle, |
| + mojo::ScopedMessagePipeHandle handle) { |
| client_channel_.Bind( |
| - mojo::InterfacePtrInfo<ClientChannel>( |
| - CreateMessagingPipe(handle.Pass()), 0u)); |
| + mojo::InterfacePtrInfo<ClientChannel>(handle.Pass(), 0u)); |
| client_channel_.set_error_handler(this); |
| client_channel_->Init( |
| - peer.Pass(), |
| - static_cast<int32_t>(GetSelfPID()), |
| + peer_handle.Pass(), static_cast<int32_t>(GetSelfPID()), |
| base::Bind(&ServerChannelMojo::ClientChannelWasInitialized, |
| base::Unretained(this))); |
| } |
| @@ -190,13 +211,26 @@ base::ScopedFD TakeOrDupFile(internal::PlatformFileAttachment* attachment) { |
| #endif |
| -} // namespace |
| +} // namespace |
| //------------------------------------------------------------------------------ |
| +ChannelMojo::ChannelInfoDeleter::ChannelInfoDeleter( |
| + scoped_refptr<base::TaskRunner> io_runner) |
| + : io_runner(io_runner) { |
| +} |
| + |
| +ChannelMojo::ChannelInfoDeleter::~ChannelInfoDeleter() { |
| +} |
| + |
| void ChannelMojo::ChannelInfoDeleter::operator()( |
| mojo::embedder::ChannelInfo* ptr) const { |
| - mojo::embedder::DestroyChannelOnIOThread(ptr); |
| + if (base::ThreadTaskRunnerHandle::Get() == io_runner) { |
| + mojo::embedder::DestroyChannelOnIOThread(ptr); |
| + } else { |
| + io_runner->PostTask( |
| + FROM_HERE, base::Bind(&mojo::embedder::DestroyChannelOnIOThread, ptr)); |
| + } |
| } |
| //------------------------------------------------------------------------------ |
| @@ -254,6 +288,7 @@ ChannelMojo::ChannelMojo(ChannelMojo::Delegate* delegate, |
| listener_(listener), |
| peer_pid_(base::kNullProcessId), |
| io_runner_(io_runner), |
| + channel_info_(nullptr, ChannelInfoDeleter(nullptr)), |
| weak_factory_(this) { |
| // Create MojoBootstrap after all members are set as it touches |
| // ChannelMojo from a different thread. |
| @@ -280,14 +315,47 @@ void ChannelMojo::InitOnIOThread(ChannelMojo::Delegate* delegate) { |
| delegate_->OnChannelCreated(weak_factory_.GetWeakPtr()); |
| } |
| -mojo::ScopedMessagePipeHandle ChannelMojo::CreateMessagingPipe( |
| - mojo::embedder::ScopedPlatformHandle handle) { |
| - DCHECK(!channel_info_.get()); |
| +void ChannelMojo::CreateMessagingPipe( |
| + mojo::embedder::ScopedPlatformHandle handle, |
| + const CreateMessagingPipeCallback& callback) { |
| + auto return_callback = base::Bind(&ChannelMojo::OnMessagingPipeCreated, |
| + weak_factory_.GetWeakPtr(), callback); |
| + if (base::ThreadTaskRunnerHandle::Get() == io_runner_) { |
| + CreateMessagingPipeOnIOThread( |
| + handle.Pass(), base::ThreadTaskRunnerHandle::Get(), return_callback); |
| + } else { |
| + io_runner_->PostTask( |
| + FROM_HERE, |
| + base::Bind(&ChannelMojo::CreateMessagingPipeOnIOThread, |
| + base::Passed(&handle), base::ThreadTaskRunnerHandle::Get(), |
| + return_callback)); |
| + } |
| +} |
| + |
| +// static |
| +void ChannelMojo::CreateMessagingPipeOnIOThread( |
| + mojo::embedder::ScopedPlatformHandle handle, |
| + scoped_refptr<base::TaskRunner> callback_runner, |
| + const CreateMessagingPipeOnIOThreadCallback& callback) { |
| mojo::embedder::ChannelInfo* channel_info; |
| mojo::ScopedMessagePipeHandle pipe = |
| mojo::embedder::CreateChannelOnIOThread(handle.Pass(), &channel_info); |
| - channel_info_.reset(channel_info); |
| - return pipe.Pass(); |
| + if (base::ThreadTaskRunnerHandle::Get() == callback_runner) { |
| + callback.Run(pipe.Pass(), channel_info); |
| + } else { |
| + callback_runner->PostTask( |
| + FROM_HERE, base::Bind(callback, base::Passed(&pipe), channel_info)); |
| + } |
| +} |
| + |
| +void ChannelMojo::OnMessagingPipeCreated( |
| + const CreateMessagingPipeCallback& callback, |
| + mojo::ScopedMessagePipeHandle handle, |
| + mojo::embedder::ChannelInfo* channel_info) { |
| + DCHECK(!channel_info_.get()); |
| + channel_info_ = scoped_ptr<mojo::embedder::ChannelInfo, ChannelInfoDeleter>( |
| + channel_info, ChannelInfoDeleter(io_runner_)); |
| + callback.Run(handle.Pass()); |
| } |
| bool ChannelMojo::Connect() { |