Merge from Chromium at DEPS revision r190564

This commit was generated by merge_to_master.py.

Change-Id: Icadecbce29854b8fa25fd335b2c1949b5ca5d170
diff --git a/chrome_frame/chrome_tab.cc b/chrome_frame/chrome_tab.cc
index 2611d69..cea60f8 100644
--- a/chrome_frame/chrome_tab.cc
+++ b/chrome_frame/chrome_tab.cc
@@ -11,6 +11,7 @@
 #include <objbase.h>
 
 #include "base/at_exit.h"
+#include "base/basictypes.h"
 #include "base/command_line.h"
 #include "base/file_util.h"
 #include "base/file_version_info.h"
@@ -40,6 +41,7 @@
 #include "chrome_frame/dll_redirector.h"
 #include "chrome_frame/exception_barrier.h"
 #include "chrome_frame/metrics_service.h"
+#include "chrome_frame/pin_module.h"
 #include "chrome_frame/resource.h"
 #include "chrome_frame/utils.h"
 #include "googleurl/src/url_util.h"
@@ -48,16 +50,6 @@
 using base::win::RegKey;
 
 namespace {
-// This function has the side effect of initializing an unprotected
-// vector pointer inside GoogleUrl. If this is called during DLL loading,
-// it has the effect of avoiding an initialization race on that pointer.
-// TODO(siggi): fix GoogleUrl.
-void InitGoogleUrl() {
-  static const char kDummyUrl[] = "http://www.google.com";
-
-  url_util::IsStandard(kDummyUrl,
-                       url_parse::MakeRange(0, arraysize(kDummyUrl)));
-}
 
 const wchar_t kInternetSettings[] =
     L"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings";
@@ -83,7 +75,7 @@
     L"ChromeFrameHelperWindowName";
 
 // {0562BFC3-2550-45b4-BD8E-A310583D3A6F}
-static const GUID kChromeFrameProvider =
+const GUID kChromeFrameProvider =
     { 0x562bfc3, 0x2550, 0x45b4,
         { 0xbd, 0x8e, 0xa3, 0x10, 0x58, 0x3d, 0x3a, 0x6f } };
 
@@ -95,11 +87,22 @@
 // See comments in DllGetClassObject.
 LPFNGETCLASSOBJECT g_dll_get_class_object_redir_ptr = NULL;
 
+// This function has the side effect of initializing an unprotected
+// vector pointer inside GoogleUrl. If this is called during DLL loading,
+// it has the effect of avoiding an initialization race on that pointer.
+// TODO(siggi): fix GoogleUrl.
+void InitGoogleUrl() {
+  static const char kDummyUrl[] = "http://www.google.com";
+
+  url_util::IsStandard(kDummyUrl,
+                       url_parse::MakeRange(0, arraysize(kDummyUrl)));
+}
+
 class ChromeTabModule : public CAtlDllModuleT<ChromeTabModule> {
  public:
   typedef CAtlDllModuleT<ChromeTabModule> ParentClass;
 
-  ChromeTabModule() : do_system_registration_(true) {}
+  ChromeTabModule() : do_system_registration_(true), crash_reporting_(NULL) {}
 
   DECLARE_LIBID(LIBID_ChromeTabLib)
   DECLARE_REGISTRY_APPID_RESOURCEID(IDR_CHROMETAB,
@@ -121,7 +124,7 @@
     }
 
     if (SUCCEEDED(hr)) {
-      FilePath app_path =
+      base::FilePath app_path =
           chrome_launcher::GetChromeExecutablePath().DirName();
       hr = registrar->AddReplacement(L"CHROME_APPPATH",
                                      app_path.value().c_str());
@@ -146,7 +149,7 @@
       // Add the directory of chrome_launcher.exe.  This will be the same
       // as the directory for the current DLL.
       std::wstring module_dir;
-      FilePath module_path;
+      base::FilePath module_path;
       if (PathService::Get(base::FILE_MODULE, &module_path)) {
         module_dir = module_path.DirName().value();
       } else {
@@ -189,8 +192,42 @@
     return hr;
   }
 
+  // The module is "locked" when an object takes a reference on it. The first
+  // time it is locked, take a reference on crash reporting to bind its lifetime
+  // to the module.
+  virtual LONG Lock() throw() {
+    LONG result = ParentClass::Lock();
+    if (result == 1) {
+      DCHECK_EQ(crash_reporting_,
+                static_cast<chrome_frame::ScopedCrashReporting*>(NULL));
+      crash_reporting_ = new chrome_frame::ScopedCrashReporting();
+    }
+    return result;
+  }
+
+  // The module is "unlocked" when an object that had a reference on it is
+  // destroyed. The last time it is unlocked, release the reference on crash
+  // reporting.
+  virtual LONG Unlock() throw() {
+    LONG result = ParentClass::Unlock();
+    if (!result) {
+      DCHECK_NE(crash_reporting_,
+                static_cast<chrome_frame::ScopedCrashReporting*>(NULL));
+      delete crash_reporting_;
+      crash_reporting_ = NULL;
+    }
+    return result;
+  }
+
   // See comments in AddCommonRGSReplacements
   bool do_system_registration_;
+
+ private:
+  // A scoper created when the module is initially locked and destroyed when it
+  // is finally unlocked. This is not a scoped_ptr since that could cause
+  // reporting to shut down at exit, which would lead to problems with the
+  // loader lock.
+  chrome_frame::ScopedCrashReporting* crash_reporting_;
 };
 
 ChromeTabModule _AtlModule;
@@ -305,8 +342,8 @@
   base::win::RemoveCommandFromAutoRun(HKEY_CURRENT_USER, kRunKeyName);
 
   // Build the chrome_frame_helper command line.
-  FilePath module_path;
-  FilePath helper_path;
+  base::FilePath module_path;
+  base::FilePath helper_path;
   if (PathService::Get(base::FILE_MODULE, &module_path)) {
     module_path = module_path.DirName();
     helper_path = module_path.Append(kChromeFrameHelperExe);
@@ -548,6 +585,11 @@
                                     HRESULT_FROM_WIN32(result2);
 }
 
+void OnPinModule() {
+  // Pin crash reporting by leaking a reference.
+  ignore_result(new chrome_frame::ScopedCrashReporting());
+}
+
 // Chrome Frame registration functions.
 //-----------------------------------------------------------------------------
 HRESULT RegisterSecuredMimeHandler(bool enable, bool is_system) {
@@ -829,7 +871,6 @@
 
     g_exit_manager = new base::AtExitManager();
     CommandLine::Init(0, NULL);
-    InitializeCrashReporting();
     logging::InitLogging(
         NULL,
         logging::LOG_ONLY_TO_SYSTEM_DEBUG_LOG,
@@ -862,6 +903,10 @@
     // can only get called once. For Chrome Frame, that is here.
     g_field_trial_list = new base::FieldTrialList(
         new metrics::SHA1EntropyProvider(MetricsService::GetClientID()));
+
+    // Set a callback so that crash reporting can be pinned when the module is
+    // pinned.
+    chrome_frame::SetPinModuleCallback(&OnPinModule);
   } else if (reason == DLL_PROCESS_DETACH) {
     delete g_field_trial_list;
     g_field_trial_list = NULL;
@@ -874,8 +919,6 @@
 
     delete g_exit_manager;
     g_exit_manager = NULL;
-
-    ShutdownCrashReporting();
   }
   return _AtlModule.DllMain(reason, reserved);
 }
@@ -887,6 +930,8 @@
 
 // Returns a class factory to create an object of the requested type
 STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) {
+  chrome_frame::ScopedCrashReporting crash_reporting;
+
   // If we found another module present when we were loaded, then delegate to
   // that:
   if (g_dll_get_class_object_redir_ptr) {
@@ -904,6 +949,7 @@
 
 // DllRegisterServer - Adds entries to the system registry
 STDAPI DllRegisterServer() {
+  chrome_frame::ScopedCrashReporting crash_reporting;
   uint16 flags =  ACTIVEX | ACTIVEDOC | TYPELIB | GCF_PROTOCOL |
                   BHO_CLSID | BHO_REGISTRATION;
 
@@ -917,12 +963,14 @@
 
 // DllUnregisterServer - Removes entries from the system registry
 STDAPI DllUnregisterServer() {
+  chrome_frame::ScopedCrashReporting crash_reporting;
   HRESULT hr = CustomRegistration(ALL, false, true);
   return hr;
 }
 
 // DllRegisterUserServer - Adds entries to the HKCU hive in the registry.
 STDAPI DllRegisterUserServer() {
+  chrome_frame::ScopedCrashReporting crash_reporting;
   UINT flags =  ACTIVEX | ACTIVEDOC | TYPELIB | GCF_PROTOCOL |
                 BHO_CLSID | BHO_REGISTRATION;
 
@@ -936,6 +984,7 @@
 
 // DllUnregisterUserServer - Removes entries from the HKCU hive in the registry.
 STDAPI DllUnregisterUserServer() {
+  chrome_frame::ScopedCrashReporting crash_reporting;
   HRESULT hr = CustomRegistration(ALL, FALSE, false);
   return hr;
 }