| OLD | NEW | 
 | (Empty) | 
|    1 // Copyright 2014 The Chromium Authors. All rights reserved. |  | 
|    2 // Use of this source code is governed by a BSD-style license that can be |  | 
|    3 // found in the LICENSE file. |  | 
|    4  |  | 
|    5 #include "mojo/edk/embedder/embedder.h" |  | 
|    6  |  | 
|    7 #include "base/bind.h" |  | 
|    8 #include "base/location.h" |  | 
|    9 #include "base/logging.h" |  | 
|   10 #include "base/memory/scoped_ptr.h" |  | 
|   11 #include "base/message_loop/message_loop_proxy.h" |  | 
|   12 #include "mojo/edk/embedder/embedder_internal.h" |  | 
|   13 #include "mojo/edk/embedder/platform_support.h" |  | 
|   14 #include "mojo/edk/system/channel.h" |  | 
|   15 #include "mojo/edk/system/channel_endpoint.h" |  | 
|   16 #include "mojo/edk/system/channel_manager.h" |  | 
|   17 #include "mojo/edk/system/configuration.h" |  | 
|   18 #include "mojo/edk/system/core.h" |  | 
|   19 #include "mojo/edk/system/message_pipe_dispatcher.h" |  | 
|   20 #include "mojo/edk/system/platform_handle_dispatcher.h" |  | 
|   21 #include "mojo/edk/system/raw_channel.h" |  | 
|   22  |  | 
|   23 namespace mojo { |  | 
|   24 namespace embedder { |  | 
|   25  |  | 
|   26 namespace { |  | 
|   27  |  | 
|   28 // Helper for |CreateChannel...()|. Returns 0 on failure. Called on the channel |  | 
|   29 // creation thread. |  | 
|   30 system::ChannelId MakeChannel( |  | 
|   31     ScopedPlatformHandle platform_handle, |  | 
|   32     scoped_refptr<system::ChannelEndpoint> channel_endpoint) { |  | 
|   33   DCHECK(platform_handle.is_valid()); |  | 
|   34  |  | 
|   35   // Create and initialize a |system::Channel|. |  | 
|   36   DCHECK(internal::g_core); |  | 
|   37   scoped_refptr<system::Channel> channel = |  | 
|   38       new system::Channel(internal::g_core->platform_support()); |  | 
|   39   channel->Init(system::RawChannel::Create(platform_handle.Pass())); |  | 
|   40   channel->SetBootstrapEndpoint(channel_endpoint); |  | 
|   41  |  | 
|   42   DCHECK(internal::g_channel_manager); |  | 
|   43   return internal::g_channel_manager->AddChannel( |  | 
|   44       channel, base::MessageLoopProxy::current()); |  | 
|   45 } |  | 
|   46  |  | 
|   47 // Helper for |CreateChannel()|. Called on the channel creation thread. |  | 
|   48 void CreateChannelHelper( |  | 
|   49     ScopedPlatformHandle platform_handle, |  | 
|   50     scoped_ptr<ChannelInfo> channel_info, |  | 
|   51     scoped_refptr<system::ChannelEndpoint> channel_endpoint, |  | 
|   52     DidCreateChannelCallback callback, |  | 
|   53     scoped_refptr<base::TaskRunner> callback_thread_task_runner) { |  | 
|   54   channel_info->channel_id = |  | 
|   55       MakeChannel(platform_handle.Pass(), channel_endpoint); |  | 
|   56  |  | 
|   57   // Hand the channel back to the embedder. |  | 
|   58   if (callback_thread_task_runner) { |  | 
|   59     callback_thread_task_runner->PostTask( |  | 
|   60         FROM_HERE, base::Bind(callback, channel_info.release())); |  | 
|   61   } else { |  | 
|   62     callback.Run(channel_info.release()); |  | 
|   63   } |  | 
|   64 } |  | 
|   65  |  | 
|   66 }  // namespace |  | 
|   67  |  | 
|   68 namespace internal { |  | 
|   69  |  | 
|   70 // Declared in embedder_internal.h. |  | 
|   71 system::Core* g_core = nullptr; |  | 
|   72 system::ChannelManager* g_channel_manager = nullptr; |  | 
|   73  |  | 
|   74 }  // namespace internal |  | 
|   75  |  | 
|   76 void Init(scoped_ptr<PlatformSupport> platform_support) { |  | 
|   77   DCHECK(!internal::g_core); |  | 
|   78   internal::g_core = new system::Core(platform_support.Pass()); |  | 
|   79   DCHECK(!internal::g_channel_manager); |  | 
|   80   internal::g_channel_manager = new system::ChannelManager(); |  | 
|   81 } |  | 
|   82  |  | 
|   83 Configuration* GetConfiguration() { |  | 
|   84   return system::GetMutableConfiguration(); |  | 
|   85 } |  | 
|   86  |  | 
|   87 // TODO(vtl): Write tests for this. |  | 
|   88 ScopedMessagePipeHandle CreateChannelOnIOThread( |  | 
|   89     ScopedPlatformHandle platform_handle, |  | 
|   90     ChannelInfo** channel_info) { |  | 
|   91   DCHECK(platform_handle.is_valid()); |  | 
|   92   DCHECK(channel_info); |  | 
|   93  |  | 
|   94   scoped_refptr<system::ChannelEndpoint> channel_endpoint; |  | 
|   95   scoped_refptr<system::MessagePipeDispatcher> dispatcher = |  | 
|   96       system::MessagePipeDispatcher::CreateRemoteMessagePipe(&channel_endpoint); |  | 
|   97  |  | 
|   98   DCHECK(internal::g_core); |  | 
|   99   ScopedMessagePipeHandle rv( |  | 
|  100       MessagePipeHandle(internal::g_core->AddDispatcher(dispatcher))); |  | 
|  101  |  | 
|  102   *channel_info = |  | 
|  103       new ChannelInfo(MakeChannel(platform_handle.Pass(), channel_endpoint)); |  | 
|  104  |  | 
|  105   return rv.Pass(); |  | 
|  106 } |  | 
|  107  |  | 
|  108 ScopedMessagePipeHandle CreateChannel( |  | 
|  109     ScopedPlatformHandle platform_handle, |  | 
|  110     scoped_refptr<base::TaskRunner> io_thread_task_runner, |  | 
|  111     DidCreateChannelCallback callback, |  | 
|  112     scoped_refptr<base::TaskRunner> callback_thread_task_runner) { |  | 
|  113   DCHECK(platform_handle.is_valid()); |  | 
|  114   DCHECK(io_thread_task_runner); |  | 
|  115   DCHECK(!callback.is_null()); |  | 
|  116  |  | 
|  117   scoped_refptr<system::ChannelEndpoint> channel_endpoint; |  | 
|  118   scoped_refptr<system::MessagePipeDispatcher> dispatcher = |  | 
|  119       system::MessagePipeDispatcher::CreateRemoteMessagePipe(&channel_endpoint); |  | 
|  120  |  | 
|  121   DCHECK(internal::g_core); |  | 
|  122   ScopedMessagePipeHandle rv( |  | 
|  123       MessagePipeHandle(internal::g_core->AddDispatcher(dispatcher))); |  | 
|  124  |  | 
|  125   // We'll have to set |channel_info->channel_id| on the I/O thread. |  | 
|  126   scoped_ptr<ChannelInfo> channel_info(new ChannelInfo()); |  | 
|  127  |  | 
|  128   if (rv.is_valid()) { |  | 
|  129     io_thread_task_runner->PostTask( |  | 
|  130         FROM_HERE, |  | 
|  131         base::Bind(&CreateChannelHelper, base::Passed(&platform_handle), |  | 
|  132                    base::Passed(&channel_info), channel_endpoint, callback, |  | 
|  133                    callback_thread_task_runner)); |  | 
|  134   } else { |  | 
|  135     (callback_thread_task_runner.get() ? callback_thread_task_runner |  | 
|  136                                        : io_thread_task_runner) |  | 
|  137         ->PostTask(FROM_HERE, base::Bind(callback, channel_info.release())); |  | 
|  138   } |  | 
|  139  |  | 
|  140   return rv.Pass(); |  | 
|  141 } |  | 
|  142  |  | 
|  143 // TODO(vtl): Write tests for this. |  | 
|  144 void DestroyChannel(ChannelInfo* channel_info) { |  | 
|  145   DCHECK(channel_info); |  | 
|  146   DCHECK(channel_info->channel_id); |  | 
|  147   DCHECK(internal::g_channel_manager); |  | 
|  148   // This will destroy the channel synchronously if called from the channel |  | 
|  149   // thread. |  | 
|  150   internal::g_channel_manager->ShutdownChannel(channel_info->channel_id); |  | 
|  151   delete channel_info; |  | 
|  152 } |  | 
|  153  |  | 
|  154 void WillDestroyChannelSoon(ChannelInfo* channel_info) { |  | 
|  155   DCHECK(channel_info); |  | 
|  156   DCHECK(internal::g_channel_manager); |  | 
|  157   internal::g_channel_manager->WillShutdownChannel(channel_info->channel_id); |  | 
|  158 } |  | 
|  159  |  | 
|  160 MojoResult CreatePlatformHandleWrapper( |  | 
|  161     ScopedPlatformHandle platform_handle, |  | 
|  162     MojoHandle* platform_handle_wrapper_handle) { |  | 
|  163   DCHECK(platform_handle_wrapper_handle); |  | 
|  164  |  | 
|  165   scoped_refptr<system::Dispatcher> dispatcher( |  | 
|  166       new system::PlatformHandleDispatcher(platform_handle.Pass())); |  | 
|  167  |  | 
|  168   DCHECK(internal::g_core); |  | 
|  169   MojoHandle h = internal::g_core->AddDispatcher(dispatcher); |  | 
|  170   if (h == MOJO_HANDLE_INVALID) { |  | 
|  171     LOG(ERROR) << "Handle table full"; |  | 
|  172     dispatcher->Close(); |  | 
|  173     return MOJO_RESULT_RESOURCE_EXHAUSTED; |  | 
|  174   } |  | 
|  175  |  | 
|  176   *platform_handle_wrapper_handle = h; |  | 
|  177   return MOJO_RESULT_OK; |  | 
|  178 } |  | 
|  179  |  | 
|  180 MojoResult PassWrappedPlatformHandle(MojoHandle platform_handle_wrapper_handle, |  | 
|  181                                      ScopedPlatformHandle* platform_handle) { |  | 
|  182   DCHECK(platform_handle); |  | 
|  183  |  | 
|  184   DCHECK(internal::g_core); |  | 
|  185   scoped_refptr<system::Dispatcher> dispatcher( |  | 
|  186       internal::g_core->GetDispatcher(platform_handle_wrapper_handle)); |  | 
|  187   if (!dispatcher) |  | 
|  188     return MOJO_RESULT_INVALID_ARGUMENT; |  | 
|  189  |  | 
|  190   if (dispatcher->GetType() != system::Dispatcher::kTypePlatformHandle) |  | 
|  191     return MOJO_RESULT_INVALID_ARGUMENT; |  | 
|  192  |  | 
|  193   *platform_handle = |  | 
|  194       static_cast<system::PlatformHandleDispatcher*>(dispatcher.get()) |  | 
|  195           ->PassPlatformHandle() |  | 
|  196           .Pass(); |  | 
|  197   return MOJO_RESULT_OK; |  | 
|  198 } |  | 
|  199  |  | 
|  200 MojoResult AsyncWait(MojoHandle handle, |  | 
|  201                      MojoHandleSignals signals, |  | 
|  202                      base::Callback<void(MojoResult)> callback) { |  | 
|  203   return internal::g_core->AsyncWait(handle, signals, callback); |  | 
|  204 } |  | 
|  205  |  | 
|  206 }  // namespace embedder |  | 
|  207 }  // namespace mojo |  | 
| OLD | NEW |