1 // Copyright (c) 2012 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 "chrome/browser/nacl_host/nacl_broker_service_win.h" 6 7 #include "chrome/browser/nacl_host/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 NaClBrokerService* NaClBrokerService::GetInstance() { 14 return Singleton<NaClBrokerService>::get(); 15 } 16 17 NaClBrokerService::NaClBrokerService() 18 : loaders_running_(0) { 19 } 20 21 bool NaClBrokerService::StartBroker() { 22 NaClBrokerHost* broker_host = new NaClBrokerHost; 23 if (!broker_host->Init()) { 24 delete broker_host; 25 return false; 26 } 27 return true; 28 } 29 30 bool NaClBrokerService::LaunchLoader( 31 base::WeakPtr<NaClProcessHost> nacl_process_host, 32 const std::string& loader_channel_id) { 33 // Add task to the list 34 pending_launches_[loader_channel_id] = nacl_process_host; 35 NaClBrokerHost* broker_host = GetBrokerHost(); 36 37 if (!broker_host) { 38 if (!StartBroker()) 39 return false; 40 broker_host = GetBrokerHost(); 41 } 42 broker_host->LaunchLoader(loader_channel_id); 43 44 return true; 45 } 46 47 void NaClBrokerService::OnLoaderLaunched(const std::string& channel_id, 48 base::ProcessHandle handle) { 49 PendingLaunchesMap::iterator it = pending_launches_.find(channel_id); 50 if (pending_launches_.end() == it) 51 NOTREACHED(); 52 53 NaClProcessHost* client = it->second.get(); 54 if (client) 55 client->OnProcessLaunchedByBroker(handle); 56 pending_launches_.erase(it); 57 ++loaders_running_; 58 } 59 60 void NaClBrokerService::OnLoaderDied() { 61 DCHECK(loaders_running_ > 0); 62 --loaders_running_; 63 // Stop the broker only if there are no loaders running or being launched. 64 NaClBrokerHost* broker_host = GetBrokerHost(); 65 if (loaders_running_ + pending_launches_.size() == 0 && broker_host != NULL) { 66 broker_host->StopBroker(); 67 } 68 } 69 70 bool NaClBrokerService::LaunchDebugExceptionHandler( 71 base::WeakPtr<NaClProcessHost> nacl_process_host, int32 pid, 72 base::ProcessHandle process_handle, const std::string& startup_info) { 73 pending_debuggers_[pid] = nacl_process_host; 74 NaClBrokerHost* broker_host = GetBrokerHost(); 75 if (!broker_host) 76 return false; 77 return broker_host->LaunchDebugExceptionHandler(pid, process_handle, 78 startup_info); 79 } 80 81 void NaClBrokerService::OnDebugExceptionHandlerLaunched(int32 pid, 82 bool success) { 83 PendingDebugExceptionHandlersMap::iterator it = pending_debuggers_.find(pid); 84 if (pending_debuggers_.end() == it) 85 NOTREACHED(); 86 87 NaClProcessHost* client = it->second.get(); 88 if (client) 89 client->OnDebugExceptionHandlerLaunchedByBroker(success); 90 pending_debuggers_.erase(it); 91 } 92 93 NaClBrokerHost* NaClBrokerService::GetBrokerHost() { 94 BrowserChildProcessHostIterator iter(PROCESS_TYPE_NACL_BROKER); 95 while (!iter.Done()) { 96 NaClBrokerHost* host = static_cast<NaClBrokerHost*>(iter.GetDelegate()); 97 if (!host->IsTerminating()) 98 return host; 99 ++iter; 100 } 101 return NULL; 102 } 103