blob: 5625117ac654536e489e21f4258a1dbebc2012f1 [file] [log] [blame]
[email protected]0ac83682010-01-22 17:46:271// Copyright (c) 2010 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/io_thread.h"
6#include "base/command_line.h"
7#include "base/leak_tracker.h"
8#include "base/logging.h"
9#include "chrome/browser/browser_process.h"
10#include "chrome/browser/chrome_thread.h"
11#include "chrome/browser/net/dns_global.h"
12#include "chrome/browser/net/url_fetcher.h"
13#include "chrome/common/chrome_switches.h"
14#include "net/base/fixed_host_resolver.h"
15#include "net/base/host_cache.h"
16#include "net/base/host_resolver.h"
17#include "net/url_request/url_request.h"
18
19namespace {
20
21net::HostResolver* CreateGlobalHostResolver() {
22 net::HostResolver* global_host_resolver = NULL;
23
24 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
25
26 // The FixedHostResolver allows us to send all network requests through
27 // a designated test server.
28 if (command_line.HasSwitch(switches::kFixedHost)) {
29 std::string host =
30 command_line.GetSwitchValueASCII(switches::kFixedHost);
31 global_host_resolver = new net::FixedHostResolver(host);
32 } else {
33 global_host_resolver = net::CreateSystemHostResolver();
34
35 if (command_line.HasSwitch(switches::kDisableIPv6))
36 global_host_resolver->SetDefaultAddressFamily(net::ADDRESS_FAMILY_IPV4);
37 }
38
39 return global_host_resolver;
40}
41
42} // namespace
43
44// The IOThread object must outlive any tasks posted to the IO thread before the
45// Quit task.
46template <>
47struct RunnableMethodTraits<IOThread> {
48 void RetainCallee(IOThread* /* io_thread */) {}
49 void ReleaseCallee(IOThread* /* io_thread */) {}
50};
51
52IOThread::IOThread()
53 : BrowserProcessSubThread(ChromeThread::IO),
54 host_resolver_(NULL),
55 prefetch_observer_(NULL),
56 dns_master_(NULL) {}
57
58IOThread::~IOThread() {
59 // We cannot rely on our base class to stop the thread since we want our
60 // CleanUp function to run.
61 Stop();
62}
63
64net::HostResolver* IOThread::host_resolver() {
65 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
66 return host_resolver_;
67}
68
69void IOThread::InitDnsMaster(
70 bool prefetching_enabled,
71 base::TimeDelta max_queue_delay,
72 size_t max_concurrent,
73 const chrome_common_net::NameList& hostnames_to_prefetch,
74 ListValue* referral_list) {
75 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
76 message_loop()->PostTask(
77 FROM_HERE,
78 NewRunnableMethod(
79 this,
80 &IOThread::InitDnsMasterOnIOThread,
81 prefetching_enabled, max_queue_delay, max_concurrent,
82 hostnames_to_prefetch, referral_list));
83}
84
85void IOThread::ChangedToOnTheRecord() {
86 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
87 message_loop()->PostTask(
88 FROM_HERE,
89 NewRunnableMethod(
90 this,
91 &IOThread::ChangedToOnTheRecordOnIOThread));
92}
93
94void IOThread::Init() {
95 BrowserProcessSubThread::Init();
96
97 DCHECK(!host_resolver_);
98 host_resolver_ = CreateGlobalHostResolver();
99 host_resolver_->AddRef();
100}
101
102void IOThread::CleanUp() {
103 // Not initialized in Init(). May not be initialized.
104 if (dns_master_) {
105 DCHECK(prefetch_observer_);
106
107 dns_master_->Shutdown();
108
109 // TODO(willchan): Stop reference counting DnsMaster. It's owned by
110 // IOThread now.
111 dns_master_->Release();
112 dns_master_ = NULL;
113 chrome_browser_net::FreeDnsPrefetchResources();
114 }
115
116 // Not initialized in Init(). May not be initialized.
117 if (prefetch_observer_) {
118 host_resolver_->RemoveObserver(prefetch_observer_);
119 delete prefetch_observer_;
120 prefetch_observer_ = NULL;
121 }
122
123 // TODO(eroman): temp hack for http://crbug.com/15513
124 host_resolver_->Shutdown();
125
126 // TODO(willchan): Stop reference counting HostResolver. It's owned by
127 // IOThread now.
128 host_resolver_->Release();
129 host_resolver_ = NULL;
130
131 // URLFetcher and URLRequest instances must NOT outlive the IO thread.
132 //
133 // Strictly speaking, URLFetcher's CheckForLeaks() should be done on the
134 // UI thread. However, since there _shouldn't_ be any instances left
135 // at this point, it shouldn't be a race.
136 //
137 // We check URLFetcher first, since if it has leaked then an associated
138 // URLRequest will also have leaked. However it is more useful to
139 // crash showing the callstack of URLFetcher's allocation than its
140 // URLRequest member.
141 base::LeakTracker<URLFetcher>::CheckForLeaks();
142 base::LeakTracker<URLRequest>::CheckForLeaks();
143
144 BrowserProcessSubThread::CleanUp();
145}
146
147void IOThread::InitDnsMasterOnIOThread(
148 bool prefetching_enabled,
149 base::TimeDelta max_queue_delay,
150 size_t max_concurrent,
151 chrome_common_net::NameList hostnames_to_prefetch,
152 ListValue* referral_list) {
153 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
154 CHECK(!dns_master_);
155
156 chrome_browser_net::EnableDnsPrefetch(prefetching_enabled);
157
158 dns_master_ = new chrome_browser_net::DnsMaster(
159 host_resolver_, max_queue_delay, max_concurrent);
160 dns_master_->AddRef();
161
162 DCHECK(!prefetch_observer_);
163 prefetch_observer_ = chrome_browser_net::CreatePrefetchObserver();
164 host_resolver_->AddObserver(prefetch_observer_);
165
166 FinalizeDnsPrefetchInitialization(
167 dns_master_, prefetch_observer_, hostnames_to_prefetch, referral_list);
168}
169
170void IOThread::ChangedToOnTheRecordOnIOThread() {
171 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
172
173 if (dns_master_) {
174 // Destroy all evidence of our OTR session.
175 dns_master_->DnsMaster::DiscardAllResults();
176 }
177
178 // Clear the host cache to avoid showing entries from the OTR session
179 // in about:net-internals.
180 net::HostCache* host_cache = host_resolver_->GetHostCache();
181 if (host_cache)
182 host_cache->clear();
183}