• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2012 The Chromium Authors
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 "components/nacl/browser/nacl_broker_service_win.h"
6 
7 #include "components/nacl/browser/nacl_process_host.h"
8 #include "components/nacl/common/nacl_process_type.h"
9 #include "content/public/browser/browser_child_process_host_iterator.h"
10 
11 using content::BrowserChildProcessHostIterator;
12 
13 namespace nacl {
14 
GetInstance()15 NaClBrokerService* NaClBrokerService::GetInstance() {
16   return base::Singleton<NaClBrokerService>::get();
17 }
18 
NaClBrokerService()19 NaClBrokerService::NaClBrokerService()
20     : loaders_running_(0) {
21 }
22 
~NaClBrokerService()23 NaClBrokerService::~NaClBrokerService() {
24 }
25 
StartBroker()26 bool NaClBrokerService::StartBroker() {
27   NaClBrokerHost* broker_host = new NaClBrokerHost;
28   if (!broker_host->Init()) {
29     delete broker_host;
30     return false;
31   }
32   return true;
33 }
34 
LaunchLoader(base::WeakPtr<nacl::NaClProcessHost> nacl_process_host,mojo::ScopedMessagePipeHandle ipc_channel_handle)35 bool NaClBrokerService::LaunchLoader(
36     base::WeakPtr<nacl::NaClProcessHost> nacl_process_host,
37     mojo::ScopedMessagePipeHandle ipc_channel_handle) {
38   // Add task to the list
39   int launch_id = ++next_launch_id_;
40   pending_launches_[launch_id] = nacl_process_host;
41   NaClBrokerHost* broker_host = GetBrokerHost();
42 
43   if (!broker_host) {
44     if (!StartBroker())
45       return false;
46     broker_host = GetBrokerHost();
47   }
48   broker_host->LaunchLoader(launch_id, std::move(ipc_channel_handle));
49 
50   return true;
51 }
52 
OnLoaderLaunched(int launch_id,base::Process process)53 void NaClBrokerService::OnLoaderLaunched(int launch_id, base::Process process) {
54   PendingLaunchesMap::iterator it = pending_launches_.find(launch_id);
55   if (pending_launches_.end() == it) {
56     NOTREACHED();
57     return;
58   }
59 
60   NaClProcessHost* client = it->second.get();
61   if (client)
62     client->OnProcessLaunchedByBroker(std::move(process));
63   pending_launches_.erase(it);
64   ++loaders_running_;
65 }
66 
OnLoaderDied()67 void NaClBrokerService::OnLoaderDied() {
68   DCHECK(loaders_running_ > 0);
69   --loaders_running_;
70   // Stop the broker only if there are no loaders running or being launched.
71   NaClBrokerHost* broker_host = GetBrokerHost();
72   if (loaders_running_ + pending_launches_.size() == 0 && broker_host != NULL) {
73     broker_host->StopBroker();
74   }
75 }
76 
LaunchDebugExceptionHandler(base::WeakPtr<NaClProcessHost> nacl_process_host,int32_t pid,base::ProcessHandle process_handle,const std::string & startup_info)77 bool NaClBrokerService::LaunchDebugExceptionHandler(
78     base::WeakPtr<NaClProcessHost> nacl_process_host,
79     int32_t pid,
80     base::ProcessHandle process_handle,
81     const std::string& startup_info) {
82   pending_debuggers_[pid] = nacl_process_host;
83   NaClBrokerHost* broker_host = GetBrokerHost();
84   if (!broker_host)
85     return false;
86   return broker_host->LaunchDebugExceptionHandler(pid, process_handle,
87                                                   startup_info);
88 }
89 
OnDebugExceptionHandlerLaunched(int32_t pid,bool success)90 void NaClBrokerService::OnDebugExceptionHandlerLaunched(int32_t pid,
91                                                         bool success) {
92   PendingDebugExceptionHandlersMap::iterator it = pending_debuggers_.find(pid);
93   if (pending_debuggers_.end() == it)
94     NOTREACHED();
95 
96   NaClProcessHost* client = it->second.get();
97   if (client)
98     client->OnDebugExceptionHandlerLaunchedByBroker(success);
99   pending_debuggers_.erase(it);
100 }
101 
GetBrokerHost()102 NaClBrokerHost* NaClBrokerService::GetBrokerHost() {
103   BrowserChildProcessHostIterator iter(PROCESS_TYPE_NACL_BROKER);
104   while (!iter.Done()) {
105     NaClBrokerHost* host = static_cast<NaClBrokerHost*>(iter.GetDelegate());
106     if (!host->IsTerminating())
107       return host;
108     ++iter;
109   }
110   return NULL;
111 }
112 
113 }  // namespace nacl
114