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) { |