Cleanup: Move the ProxyScriptFetcher registry from being a global in net, to living in IOThread.

I had to make some other changes to make this fit well: moved ProxyScriptFetcherImpl to its own set of files, and added a IOThread::Get() accessor to avoid plumbing through several layers in connection_tester.

I find the registry living in IOThread is preferable, as globals in net/ limit the ability to run on safely on multiple threads, and also leads to confusion on what needs to be called at shutdown.

Review URL: http://codereview.chromium.org/3823001

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@62876 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/io_thread.cc b/chrome/browser/io_thread.cc
index 8a18541b..ae64b80 100644
--- a/chrome/browser/io_thread.cc
+++ b/chrome/browser/io_thread.cc
@@ -7,6 +7,7 @@
 #include "base/command_line.h"
 #include "base/leak_tracker.h"
 #include "base/logging.h"
+#include "base/stl_util-inl.h"
 #include "base/string_number_conversions.h"
 #include "base/string_split.h"
 #include "base/string_util.h"
@@ -15,22 +16,22 @@
 #include "chrome/browser/gpu_process_host.h"
 #include "chrome/browser/net/chrome_net_log.h"
 #include "chrome/browser/net/connect_interceptor.h"
-#include "chrome/browser/net/predictor_api.h"
 #include "chrome/browser/net/passive_log_collector.h"
+#include "chrome/browser/net/predictor_api.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/net/url_fetcher.h"
 #include "net/base/dnsrr_resolver.h"
-#include "net/base/mapped_host_resolver.h"
 #include "net/base/host_cache.h"
 #include "net/base/host_resolver.h"
 #include "net/base/host_resolver_impl.h"
+#include "net/base/mapped_host_resolver.h"
 #include "net/base/net_util.h"
 #include "net/http/http_auth_filter.h"
 #include "net/http/http_auth_handler_factory.h"
 #if defined(USE_NSS)
 #include "net/ocsp/nss_ocsp.h"
 #endif  // defined(USE_NSS)
-#include "net/proxy/proxy_script_fetcher.h"
+#include "net/proxy/proxy_script_fetcher_impl.h"
 
 namespace {
 
@@ -113,6 +114,34 @@
 
 }  // namespace
 
+// This is a wrapper class around ProxyScriptFetcherImpl that will
+// keep track of live instances.
+class IOThread::ManagedProxyScriptFetcher
+    : public net::ProxyScriptFetcherImpl {
+ public:
+  ManagedProxyScriptFetcher(URLRequestContext* context,
+                            IOThread* io_thread)
+      : net::ProxyScriptFetcherImpl(context),
+        io_thread_(io_thread) {
+    DCHECK(!ContainsKey(*fetchers(), this));
+    fetchers()->insert(this);
+  }
+
+  virtual ~ManagedProxyScriptFetcher() {
+    DCHECK(ContainsKey(*fetchers(), this));
+    fetchers()->erase(this);
+  }
+
+ private:
+  ProxyScriptFetchers* fetchers() {
+    return &io_thread_->fetchers_;
+  }
+
+  IOThread* io_thread_;
+
+  DISALLOW_COPY_AND_ASSIGN(ManagedProxyScriptFetcher);
+};
+
 // The IOThread object must outlive any tasks posted to the IO thread before the
 // Quit task.
 DISABLE_RUNNABLE_METHOD_REFCOUNT(IOThread);
@@ -165,6 +194,11 @@
           &IOThread::ChangedToOnTheRecordOnIOThread));
 }
 
+net::ProxyScriptFetcher* IOThread::CreateAndRegisterProxyScriptFetcher(
+    URLRequestContext* url_request_context) {
+  return new ManagedProxyScriptFetcher(url_request_context, this);
+}
+
 void IOThread::Init() {
   BrowserProcessSubThread::Init();
 
@@ -221,7 +255,11 @@
     globals_->host_resolver.get()->GetAsHostResolverImpl()->Shutdown();
   }
 
-  net::EnsureNoProxyScriptFetches();
+  // Break any cycles between the ProxyScriptFetcher and URLRequestContext.
+  for (ProxyScriptFetchers::const_iterator it = fetchers_.begin();
+       it != fetchers_.end(); ++it) {
+    (*it)->Cancel();
+  }
 
   // We will delete the NetLog as part of CleanUpAfterMessageLoopDestruction()
   // in case any of the message loop destruction observers try to access it.