diff options
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/child_process_host.h | 6 | ||||
-rw-r--r-- | chrome/browser/nacl_host/nacl_broker_host.cc | 18 | ||||
-rw-r--r-- | chrome/browser/nacl_host/nacl_broker_host.h | 8 | ||||
-rw-r--r-- | chrome/browser/nacl_host/nacl_broker_service.cc | 38 | ||||
-rw-r--r-- | chrome/browser/nacl_host/nacl_broker_service.h | 7 | ||||
-rw-r--r-- | chrome/browser/nacl_host/nacl_process_host.cc | 9 | ||||
-rw-r--r-- | chrome/browser/nacl_host/nacl_process_host.h | 1 | ||||
-rw-r--r-- | chrome/common/nacl_messages_internal.h | 4 | ||||
-rw-r--r-- | chrome/nacl/broker_thread.cc | 9 | ||||
-rw-r--r-- | chrome/nacl/broker_thread.h | 1 |
10 files changed, 86 insertions, 15 deletions
diff --git a/chrome/browser/child_process_host.h b/chrome/browser/child_process_host.h index 735bcd8..c7c27be 100644 --- a/chrome/browser/child_process_host.h +++ b/chrome/browser/child_process_host.h @@ -118,13 +118,13 @@ class ChildProcessHost : public ResourceDispatcherHost::Receiver, virtual bool DidChildCrash(); + // Called when the child process goes away. + virtual void OnChildDied(); + private: // Sends the given notification to the notification service on the UI thread. void Notify(NotificationType type); - // Called when the child process goes away. - void OnChildDied(); - // By using an internal class as the IPC::Channel::Listener, we can intercept // OnMessageReceived/OnChannelConnected and do our own processing before // calling the subclass' implementation. diff --git a/chrome/browser/nacl_host/nacl_broker_host.cc b/chrome/browser/nacl_host/nacl_broker_host.cc index 92ed181..ec8aafd 100644 --- a/chrome/browser/nacl_host/nacl_broker_host.cc +++ b/chrome/browser/nacl_host/nacl_broker_host.cc @@ -16,7 +16,8 @@ NaClBrokerHost::NaClBrokerHost( ResourceDispatcherHost* resource_dispatcher_host) - : ChildProcessHost(NACL_BROKER_PROCESS, resource_dispatcher_host) { + : ChildProcessHost(NACL_BROKER_PROCESS, resource_dispatcher_host), + stopping_(false) { } NaClBrokerHost::~NaClBrokerHost() { @@ -72,3 +73,18 @@ void NaClBrokerHost::OnLoaderLaunched(const std::wstring& loader_channel_id, base::ProcessHandle handle) { NaClBrokerService::GetInstance()->OnLoaderLaunched(loader_channel_id, handle); } + +void NaClBrokerHost::StopBroker() { + stopping_ = true; + Send(new NaClProcessMsg_StopBroker()); +} + +void NaClBrokerHost::OnChildDied() { + if (!stopping_) { + // If the broker stops unexpectedly (and not when asked by the broker + // service), we need to notify the broker service. In any other case + // the broker service may have a new broker host pointer by this time. + NaClBrokerService::GetInstance()->OnBrokerDied(); + } + ChildProcessHost::OnChildDied(); +} diff --git a/chrome/browser/nacl_host/nacl_broker_host.h b/chrome/browser/nacl_host/nacl_broker_host.h index 15dd18b..47c3e95 100644 --- a/chrome/browser/nacl_host/nacl_broker_host.h +++ b/chrome/browser/nacl_host/nacl_broker_host.h @@ -23,6 +23,12 @@ class NaClBrokerHost : public ChildProcessHost { // a Native Client loader process. bool LaunchLoader(const std::wstring& loader_channel_id); + // Stop the broker process. + void StopBroker(); + + protected: + virtual void OnChildDied(); + private: // ResourceDispatcherHost::Receiver implementation: virtual URLRequestContext* GetRequestContext( @@ -40,6 +46,8 @@ class NaClBrokerHost : public ChildProcessHost { // IPC::Channel::Listener virtual void OnMessageReceived(const IPC::Message& msg); + bool stopping_; + DISALLOW_COPY_AND_ASSIGN(NaClBrokerHost); }; diff --git a/chrome/browser/nacl_host/nacl_broker_service.cc b/chrome/browser/nacl_host/nacl_broker_service.cc index 6a58c2f..69c919b 100644 --- a/chrome/browser/nacl_host/nacl_broker_service.cc +++ b/chrome/browser/nacl_host/nacl_broker_service.cc @@ -15,16 +15,18 @@ NaClBrokerService* NaClBrokerService::GetInstance() { NaClBrokerService::NaClBrokerService() : broker_started_(false), broker_host_(NULL), + loaders_running_(0), resource_dispatcher_host_(NULL), initialized_(false) { } void NaClBrokerService::Init(ResourceDispatcherHost* resource_dispatcher_host) { - if (initialized_) { - return; - } - resource_dispatcher_host_ = resource_dispatcher_host; - StartBroker(); + if (!initialized_) + resource_dispatcher_host_ = resource_dispatcher_host; + + if (broker_host_ == NULL) + StartBroker(); + initialized_ = true; } @@ -51,9 +53,9 @@ bool NaClBrokerService::LaunchLoader(NaClProcessHost* nacl_process_host, void NaClBrokerService::OnBrokerStarted() { PendingLaunchesMap::iterator it; - for (it = pending_launches_.begin(); it != pending_launches_.end(); it++) { + for (it = pending_launches_.begin(); it != pending_launches_.end(); it++) broker_host_->LaunchLoader(it->first); - } + broker_started_ = true; } @@ -61,10 +63,28 @@ void NaClBrokerService::OnLoaderLaunched(const std::wstring& channel_id, base::ProcessHandle handle) { NaClProcessHost* client; PendingLaunchesMap::iterator it = pending_launches_.find(channel_id); - if (pending_launches_.end() == it) { + if (pending_launches_.end() == it) NOTREACHED(); - } + client = it->second; client->OnProcessLaunchedByBroker(handle); pending_launches_.erase(it); + ++loaders_running_; +} + +void NaClBrokerService::OnLoaderDied() { + --loaders_running_; + // Stop the broker only if there are no loaders running or being launched. + if (loaders_running_ + pending_launches_.size() == 0 && + broker_host_ != NULL) { + broker_host_->StopBroker(); + // Reset the pointer to the broker host. + OnBrokerDied(); + } +} + +void NaClBrokerService::OnBrokerDied() { + // NaClBrokerHost object will be destructed by ChildProcessHost + broker_started_ = false; + broker_host_.release(); } diff --git a/chrome/browser/nacl_host/nacl_broker_service.h b/chrome/browser/nacl_host/nacl_broker_service.h index 75e089d..8518cd4 100644 --- a/chrome/browser/nacl_host/nacl_broker_service.h +++ b/chrome/browser/nacl_host/nacl_broker_service.h @@ -36,6 +36,12 @@ class NaClBrokerService { void OnLoaderLaunched(const std::wstring& channel_id, base::ProcessHandle handle); + // Called by NaClProcessHost when a loader process is terminated + void OnLoaderDied(); + + // Called by NaClBrokerHost when the broker process is terminated. + void OnBrokerDied(); + private: typedef std::map<std::wstring, NaClProcessHost*> PendingLaunchesMap; @@ -47,6 +53,7 @@ class NaClBrokerService { bool broker_started_; scoped_ptr<NaClBrokerHost> broker_host_; + int loaders_running_; bool initialized_; ResourceDispatcherHost* resource_dispatcher_host_; PendingLaunchesMap pending_launches_; diff --git a/chrome/browser/nacl_host/nacl_process_host.cc b/chrome/browser/nacl_host/nacl_process_host.cc index 9a08d54..1114cb7 100644 --- a/chrome/browser/nacl_host/nacl_process_host.cc +++ b/chrome/browser/nacl_host/nacl_process_host.cc @@ -125,10 +125,17 @@ bool NaClProcessHost::DidChildCrash() { return ChildProcessHost::DidChildCrash(); } +void NaClProcessHost::OnChildDied() { +#if defined(OS_WIN) + NaClBrokerService::GetInstance()->OnLoaderDied(); +#endif + ChildProcessHost::OnChildDied(); +} + void NaClProcessHost::OnProcessLaunched() { nacl::FileDescriptor imc_handle; base::ProcessHandle nacl_process_handle; -#if NACL_WINDOWS +#if defined(OS_WIN) // Duplicate the IMC handle // We assume the size of imc_handle has the same size as HANDLE, so the cast // below is safe. diff --git a/chrome/browser/nacl_host/nacl_process_host.h b/chrome/browser/nacl_host/nacl_process_host.h index a89b2da..28893fc 100644 --- a/chrome/browser/nacl_host/nacl_process_host.h +++ b/chrome/browser/nacl_host/nacl_process_host.h @@ -37,6 +37,7 @@ class NaClProcessHost : public ChildProcessHost { protected: virtual bool DidChildCrash(); + virtual void OnChildDied(); private: bool LaunchSelLdr(); diff --git a/chrome/common/nacl_messages_internal.h b/chrome/common/nacl_messages_internal.h index 11dfba7..9eec408 100644 --- a/chrome/common/nacl_messages_internal.h +++ b/chrome/common/nacl_messages_internal.h @@ -25,5 +25,9 @@ IPC_BEGIN_MESSAGES(NaClProcess) // Notify the browser process that the broker is ready (sent by the broker) IPC_MESSAGE_CONTROL0(NaClProcessMsg_BrokerReady) + + // Notify the broker that all loader processes have been terminated and it + // should shutdown. + IPC_MESSAGE_CONTROL0(NaClProcessMsg_StopBroker) IPC_END_MESSAGES(NaClProcess) diff --git a/chrome/nacl/broker_thread.cc b/chrome/nacl/broker_thread.cc index 832c73a7..f94d49d 100644 --- a/chrome/nacl/broker_thread.cc +++ b/chrome/nacl/broker_thread.cc @@ -8,10 +8,11 @@ #include "base/command_line.h" #include "base/path_service.h" #include "base/process_util.h" -#include "chrome/common/sandbox_policy.h" +#include "chrome/common/child_process.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/nacl_cmd_line.h" #include "chrome/common/nacl_messages.h" +#include "chrome/common/sandbox_policy.h" #include "ipc/ipc_switches.h" NaClBrokerThread::NaClBrokerThread() @@ -31,6 +32,7 @@ void NaClBrokerThread::OnControlMessageReceived(const IPC::Message& msg) { IPC_BEGIN_MESSAGE_MAP(NaClBrokerThread, msg) IPC_MESSAGE_HANDLER(NaClProcessMsg_LaunchLoaderThroughBroker, OnLaunchLoaderThroughBroker) + IPC_MESSAGE_HANDLER(NaClProcessMsg_StopBroker, OnStopBroker) IPC_END_MESSAGE_MAP() } @@ -64,9 +66,14 @@ void NaClBrokerThread::OnLaunchLoaderThroughBroker( loader_handle_in_browser)); } +void NaClBrokerThread::OnStopBroker() { + ChildProcess::current()->ReleaseProcess(); +} + void NaClBrokerThread::OnChannelConnected(int32 peer_pid) { bool res = base::OpenProcessHandle(peer_pid, &browser_handle_); DCHECK(res); + ChildProcess::current()->AddRefProcess(); Send(new NaClProcessMsg_BrokerReady()); } diff --git a/chrome/nacl/broker_thread.h b/chrome/nacl/broker_thread.h index d88919f..fb4cf40 100644 --- a/chrome/nacl/broker_thread.h +++ b/chrome/nacl/broker_thread.h @@ -27,6 +27,7 @@ class NaClBrokerThread : public ChildThread { virtual void OnControlMessageReceived(const IPC::Message& msg); void OnLaunchLoaderThroughBroker(const std::wstring& loader_channel_id); void OnShareBrowserHandle(int browser_handle); + void OnStopBroker(); base::ProcessHandle browser_handle_; sandbox::BrokerServices* broker_services_; |