Home | History | Annotate | Download | only in nacl_host
      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