| Index: mojo/embedder/embedder.cc
|
| diff --git a/mojo/embedder/embedder.cc b/mojo/embedder/embedder.cc
|
| index 703b8e44c0f8cd58ccbe31bf931b686695ec917e..674e7c205073565d53748956f5321622f85ecffe 100644
|
| --- a/mojo/embedder/embedder.cc
|
| +++ b/mojo/embedder/embedder.cc
|
| @@ -24,17 +24,19 @@ namespace embedder {
|
| // outside world. But we need to define it before our (internal-only) functions
|
| // that use it.
|
| struct ChannelInfo {
|
| - explicit ChannelInfo(scoped_refptr<system::Channel> channel)
|
| - : channel(channel) {}
|
| + ChannelInfo() {}
|
| ~ChannelInfo() {}
|
|
|
| scoped_refptr<system::Channel> channel;
|
| +
|
| + // May be null, in which case |DestroyChannelOnIOThread()| must be used (from
|
| + // the IO thread), instead of |DestroyChannel()|.
|
| + scoped_refptr<base::TaskRunner> io_thread_task_runner;
|
| };
|
|
|
| namespace {
|
|
|
| -// Helper for |CreateChannelOnIOThread()|. (Note: May return null for some
|
| -// failures.)
|
| +// Helper for |CreateChannel...()|. (Note: May return null for some failures.)
|
| scoped_refptr<system::Channel> MakeChannel(
|
| ScopedPlatformHandle platform_handle,
|
| scoped_refptr<system::MessagePipe> message_pipe) {
|
| @@ -73,13 +75,13 @@ scoped_refptr<system::Channel> MakeChannel(
|
| return channel;
|
| }
|
|
|
| -void CreateChannelOnIOThread(
|
| +void CreateChannelHelper(
|
| ScopedPlatformHandle platform_handle,
|
| + scoped_ptr<ChannelInfo> channel_info,
|
| scoped_refptr<system::MessagePipe> message_pipe,
|
| DidCreateChannelCallback callback,
|
| scoped_refptr<base::TaskRunner> callback_thread_task_runner) {
|
| - scoped_ptr<ChannelInfo> channel_info(
|
| - new ChannelInfo(MakeChannel(platform_handle.Pass(), message_pipe)));
|
| + channel_info->channel = MakeChannel(platform_handle.Pass(), message_pipe);
|
|
|
| // Hand the channel back to the embedder.
|
| if (callback_thread_task_runner) {
|
| @@ -96,6 +98,29 @@ void Init() {
|
| system::entrypoints::SetCore(new system::Core());
|
| }
|
|
|
| +// TODO(vtl): Write tests for this.
|
| +ScopedMessagePipeHandle CreateChannelOnIOThread(
|
| + ScopedPlatformHandle platform_handle,
|
| + ChannelInfo** channel_info) {
|
| + DCHECK(platform_handle.is_valid());
|
| + DCHECK(channel_info);
|
| +
|
| + std::pair<scoped_refptr<system::MessagePipeDispatcher>,
|
| + scoped_refptr<system::MessagePipe> > remote_message_pipe =
|
| + system::MessagePipeDispatcher::CreateRemoteMessagePipe();
|
| +
|
| + system::Core* core = system::entrypoints::GetCore();
|
| + DCHECK(core);
|
| + ScopedMessagePipeHandle rv(
|
| + MessagePipeHandle(core->AddDispatcher(remote_message_pipe.first)));
|
| +
|
| + *channel_info = new ChannelInfo();
|
| + (*channel_info)->channel =
|
| + MakeChannel(platform_handle.Pass(), remote_message_pipe.second);
|
| +
|
| + return rv.Pass();
|
| +}
|
| +
|
| ScopedMessagePipeHandle CreateChannel(
|
| ScopedPlatformHandle platform_handle,
|
| scoped_refptr<base::TaskRunner> io_thread_task_runner,
|
| @@ -111,15 +136,24 @@ ScopedMessagePipeHandle CreateChannel(
|
| DCHECK(core);
|
| ScopedMessagePipeHandle rv(
|
| MessagePipeHandle(core->AddDispatcher(remote_message_pipe.first)));
|
| - // TODO(vtl): Do we properly handle the failure case here?
|
| +
|
| + scoped_ptr<ChannelInfo> channel_info(new ChannelInfo());
|
| + channel_info->io_thread_task_runner = io_thread_task_runner;
|
| +
|
| if (rv.is_valid()) {
|
| io_thread_task_runner->PostTask(FROM_HERE,
|
| - base::Bind(&CreateChannelOnIOThread,
|
| + base::Bind(&CreateChannelHelper,
|
| base::Passed(&platform_handle),
|
| + base::Passed(&channel_info),
|
| remote_message_pipe.second,
|
| callback,
|
| callback_thread_task_runner));
|
| + } else {
|
| + (callback_thread_task_runner ? callback_thread_task_runner
|
| + : io_thread_task_runner)
|
| + ->PostTask(FROM_HERE, base::Bind(callback, channel_info.release()));
|
| }
|
| +
|
| return rv.Pass();
|
| }
|
|
|
| @@ -134,6 +168,15 @@ void DestroyChannelOnIOThread(ChannelInfo* channel_info) {
|
| delete channel_info;
|
| }
|
|
|
| +// TODO(vtl): Write tests for this.
|
| +void DestroyChannel(ChannelInfo* channel_info) {
|
| + DCHECK(channel_info);
|
| + DCHECK(channel_info->io_thread_task_runner);
|
| +
|
| + channel_info->io_thread_task_runner->PostTask(
|
| + FROM_HERE, base::Bind(&DestroyChannelOnIOThread, channel_info));
|
| +}
|
| +
|
| MojoResult CreatePlatformHandleWrapper(
|
| ScopedPlatformHandle platform_handle,
|
| MojoHandle* platform_handle_wrapper_handle) {
|
|
|