Chromium Code Reviews| Index: components/nacl/renderer/ppb_nacl_private_impl.cc |
| diff --git a/components/nacl/renderer/ppb_nacl_private_impl.cc b/components/nacl/renderer/ppb_nacl_private_impl.cc |
| index 1a3f204deef7ca3338154bcc57ce0c135977ebf9..7daf05aea1902792aff989bd3dbc77e8c4ae5a63 100644 |
| --- a/components/nacl/renderer/ppb_nacl_private_impl.cc |
| +++ b/components/nacl/renderer/ppb_nacl_private_impl.cc |
| @@ -13,6 +13,7 @@ |
| #include "components/nacl/common/nacl_messages.h" |
| #include "components/nacl/common/nacl_switches.h" |
| #include "components/nacl/common/nacl_types.h" |
| +#include "components/nacl/renderer/embedder_service_channel.h" |
| #include "components/nacl/renderer/nexe_load_manager.h" |
| #include "components/nacl/renderer/pnacl_translation_resource_host.h" |
| #include "components/nacl/renderer/sandbox_arch.h" |
| @@ -104,6 +105,40 @@ bool IsValidChannelHandle(const IPC::ChannelHandle& channel_handle) { |
| return true; |
| } |
| +struct LaunchSelLdrCompletionCallbackData : |
|
dmichael (off chromium)
2014/04/10 18:06:23
A brief description of what the class does might b
hidehiko
2014/04/10 19:02:08
Done.
|
| + public base::RefCounted<LaunchSelLdrCompletionCallbackData> { |
| + public: |
| + LaunchSelLdrCompletionCallbackData(int num_expect_call) |
|
dmichael (off chromium)
2014/04/10 18:06:23
nit: explicit
hidehiko
2014/04/10 19:02:08
Acknowledged.
|
| + : num_remaining_call(num_expect_call), |
| + result(PP_OK) { |
| + } |
| + int num_remaining_call; |
|
dmichael (off chromium)
2014/04/10 18:06:23
nit: call->calls
hidehiko
2014/04/10 19:02:08
Done.
|
| + int32_t result; |
| + |
| + private: |
| + friend class base::RefCounted<LaunchSelLdrCompletionCallbackData>; |
| + ~LaunchSelLdrCompletionCallbackData() { |
| + } |
| +}; |
| + |
| +void LaunchSelLdrCompletionCallback( |
|
dmichael (off chromium)
2014/04/10 18:06:23
suggestion: It might simplify things a tiny bit to
hidehiko
2014/04/10 19:02:08
Good idea. How about this?
|
| + scoped_refptr<LaunchSelLdrCompletionCallbackData> data, |
| + PP_CompletionCallback callback, |
| + int32_t result) { |
| + if (data->result == PP_OK && result != PP_OK) |
| + data->result = result; |
| + |
| + --data->num_remaining_call; |
| + if (data->num_remaining_call > 0) { |
| + // There still are some pending or on-going tasks. Wait for the results. |
| + return; |
| + } |
| + |
| + ppapi::PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask( |
| + FROM_HERE, |
| + base::Bind(callback.func, callback.user_data, data->result)); |
| +} |
| + |
| // Launch NaCl's sel_ldr process. |
| void LaunchSelLdr(PP_Instance instance, |
| const char* alleged_url, |
| @@ -191,15 +226,17 @@ void LaunchSelLdr(PP_Instance instance, |
| *(static_cast<NaClHandle*>(imc_handle)) = |
| nacl::ToNativeHandle(result_socket); |
| - // TODO(hidehiko): We'll add EmbedderServiceChannel here, and it will wait |
| - // for the connection in parallel with TrustedPluginChannel. |
| - // Thus, the callback will wait for its second invocation to run callback, |
| - // then. |
| + // Here after we start to establish TrustedPluginChannel and |
| + // EmbedderServiceChannel in parallel. So, we count the number of connections |
| + // (or errors), and invoke callback when all the connections are established. |
| // Note that PP_CompletionCallback is not designed to be called twice or |
| // more. Thus, it is necessary to create a function to handle multiple |
| // invocation. |
| - base::Callback<void(int32_t)> completion_callback = |
| - base::Bind(callback.func, callback.user_data); |
| + base::Callback<void(int32_t)> completion_callback = base::Bind( |
| + &LaunchSelLdrCompletionCallback, |
| + make_scoped_refptr(new LaunchSelLdrCompletionCallbackData(2)), |
| + callback); |
| + |
| nacl::NexeLoadManager* load_manager = GetNexeLoadManager(instance); |
| DCHECK(load_manager); |
| @@ -215,6 +252,24 @@ void LaunchSelLdr(PP_Instance instance, |
| } else { |
| completion_callback.Run(PP_ERROR_FAILED); |
| } |
| + |
| + // Stash the embedder service handle as well. |
| + if (load_manager && |
| + IsValidChannelHandle( |
| + launch_result.embedder_service_ipc_channel_handle)) { |
| + scoped_ptr<nacl::EmbedderServiceChannel> embedder_service_channel( |
| + new nacl::EmbedderServiceChannel( |
| + launch_result.embedder_service_ipc_channel_handle, |
| + completion_callback, |
| + content::RenderThread::Get()->GetShutdownEvent())); |
| + load_manager->set_embedder_service_channel( |
| + embedder_service_channel.Pass()); |
| + } else { |
| + // Currently, embedder service works only on linux/non-SFI mode. |
| + // On other platforms, the socket will not be created, and thus this |
| + // condition needs to be handled as success. |
| + completion_callback.Run(PP_OK); |
| + } |
| } |
| // Forward declaration. |