1 /* 2 * Copyright (c) 2012 The Chromium Authors. All rights reserved. 3 * Use of this source code is governed by a BSD-style license that can be 4 * found in the LICENSE file. 5 */ 6 7 #include "native_client/src/shared/imc/nacl_imc_c.h" 8 #include "native_client/src/shared/platform/nacl_time.h" 9 #include "native_client/src/trusted/desc/nrd_all_modules.h" 10 11 12 #include "ppapi/native_client/src/trusted/plugin/module_ppapi.h" 13 #include "ppapi/native_client/src/trusted/plugin/nacl_entry_points.h" 14 #include "ppapi/native_client/src/trusted/plugin/plugin.h" 15 16 namespace plugin { 17 18 ModulePpapi::ModulePpapi() : pp::Module(), 19 init_was_successful_(false), 20 private_interface_(NULL) { 21 MODULE_PRINTF(("ModulePpapi::ModulePpapi (this=%p)\n", 22 static_cast<void*>(this))); 23 } 24 25 ModulePpapi::~ModulePpapi() { 26 if (init_was_successful_) { 27 NaClSrpcModuleFini(); 28 NaClNrdAllModulesFini(); 29 } 30 MODULE_PRINTF(("ModulePpapi::~ModulePpapi (this=%p)\n", 31 static_cast<void*>(this))); 32 } 33 34 bool ModulePpapi::Init() { 35 // Ask the browser for an interface which provides missing functions 36 private_interface_ = reinterpret_cast<const PPB_NaCl_Private*>( 37 GetBrowserInterface(PPB_NACL_PRIVATE_INTERFACE)); 38 39 if (NULL == private_interface_) { 40 MODULE_PRINTF(("ModulePpapi::Init failed: " 41 "GetBrowserInterface returned NULL\n")); 42 return false; 43 } 44 45 launch_nacl_process = reinterpret_cast<LaunchNaClProcessFunc>( 46 private_interface_->LaunchSelLdr); 47 48 #if NACL_LINUX || NACL_OSX 49 // Note that currently we do not need random numbers inside the 50 // NaCl trusted plugin on Unix, but NaClSecureRngModuleInit() is 51 // strict and will raise a fatal error unless we provide it with a 52 // /dev/urandom FD beforehand. 53 NaClSecureRngModuleSetUrandomFd(dup(private_interface_->UrandomFD())); 54 #endif 55 56 // In the plugin, we don't need high resolution time of day. 57 NaClAllowLowResolutionTimeOfDay(); 58 NaClNrdAllModulesInit(); 59 NaClSrpcModuleInit(); 60 61 #if NACL_WINDOWS 62 NaClSetBrokerDuplicateHandleFunc(private_interface_->BrokerDuplicateHandle); 63 #endif 64 65 init_was_successful_ = true; 66 return true; 67 } 68 69 pp::Instance* ModulePpapi::CreateInstance(PP_Instance pp_instance) { 70 MODULE_PRINTF(("ModulePpapi::CreateInstance (pp_instance=%" NACL_PRId32 71 ")\n", 72 pp_instance)); 73 Plugin* plugin = Plugin::New(pp_instance); 74 MODULE_PRINTF(("ModulePpapi::CreateInstance (return %p)\n", 75 static_cast<void* >(plugin))); 76 return plugin; 77 } 78 79 const uint64_t kMaxCrashesPerInterval = 3; 80 const uint64_t kCrashesIntervalInSeconds = 120; 81 82 void ModulePpapi::RegisterPluginCrash() { 83 PLUGIN_PRINTF(("ModulePpapi::RegisterPluginCrash ()\n")); 84 if (crash_times_.size() == kMaxCrashesPerInterval) { 85 crash_times_.pop_front(); 86 } 87 int64_t time = NaClGetTimeOfDayMicroseconds(); 88 crash_times_.push_back(time); 89 } 90 91 bool ModulePpapi::IsPluginUnstable() { 92 PLUGIN_PRINTF(("ModulePpapi::IsPluginUnstable ()\n")); 93 if (crash_times_.size() != kMaxCrashesPerInterval) { 94 return false; 95 } 96 int64_t now = NaClGetTimeOfDayMicroseconds(); 97 int64_t delta = now - crash_times_.front(); 98 return delta / (1000.0 * 1000.0) <= kCrashesIntervalInSeconds; 99 } 100 101 } // namespace plugin 102 103 104 namespace pp { 105 106 Module* CreateModule() { 107 MODULE_PRINTF(("CreateModule ()\n")); 108 return new plugin::ModulePpapi(); 109 } 110 111 } // namespace pp 112