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