summaryrefslogtreecommitdiffstats
path: root/net/proxy/dhcp_proxy_script_fetcher_win.cc
diff options
context:
space:
mode:
authorjoi@chromium.org <joi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-23 20:34:58 +0000
committerjoi@chromium.org <joi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-23 20:34:58 +0000
commitc24ebc31b665f800a3d51eea012d91bc2728364d (patch)
treedc717b354436761c3de6ab1fe30e1925293a4b8f /net/proxy/dhcp_proxy_script_fetcher_win.cc
parentff04c53708ec68d1f6b1aefa2d44df1725cdf7eb (diff)
downloadchromium_src-c24ebc31b665f800a3d51eea012d91bc2728364d.zip
chromium_src-c24ebc31b665f800a3d51eea012d91bc2728364d.tar.gz
chromium_src-c24ebc31b665f800a3d51eea012d91bc2728364d.tar.bz2
Do GetAdaptersAddresses on a worker thread.
BUG=84047 TEST=net_unittests Review URL: http://codereview.chromium.org/7189016 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@90258 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/proxy/dhcp_proxy_script_fetcher_win.cc')
-rw-r--r--net/proxy/dhcp_proxy_script_fetcher_win.cc156
1 files changed, 111 insertions, 45 deletions
diff --git a/net/proxy/dhcp_proxy_script_fetcher_win.cc b/net/proxy/dhcp_proxy_script_fetcher_win.cc
index dbe4df2..2c7fd23 100644
--- a/net/proxy/dhcp_proxy_script_fetcher_win.cc
+++ b/net/proxy/dhcp_proxy_script_fetcher_win.cc
@@ -6,6 +6,7 @@
#include "base/metrics/histogram.h"
#include "base/perftimer.h"
+#include "base/threading/worker_pool.h"
#include "net/base/net_errors.h"
#include "net/proxy/dhcp_proxy_script_adapter_fetcher_win.h"
@@ -45,6 +46,11 @@ DhcpProxyScriptFetcherWin::DhcpProxyScriptFetcherWin(
DhcpProxyScriptFetcherWin::~DhcpProxyScriptFetcherWin() {
// Count as user-initiated if we are not yet in STATE_DONE.
Cancel();
+
+ // The WeakPtr we passed to the worker thread may be destroyed on the
+ // worker thread. This detaches any outstanding WeakPtr state from
+ // the current thread.
+ base::SupportsWeakPtr<DhcpProxyScriptFetcherWin>::DetachFromThread();
}
int DhcpProxyScriptFetcherWin::Fetch(string16* utf16_text,
@@ -57,27 +63,12 @@ int DhcpProxyScriptFetcherWin::Fetch(string16* utf16_text,
fetch_start_time_ = base::TimeTicks::Now();
- std::set<std::string> adapter_names;
- if (!ImplGetCandidateAdapterNames(&adapter_names)) {
- return ERR_UNEXPECTED;
- }
- if (adapter_names.empty()) {
- return ERR_PAC_NOT_IN_DHCP;
- }
-
- state_ = STATE_NO_RESULTS;
-
+ state_ = STATE_WAIT_ADAPTERS;
client_callback_ = callback;
destination_string_ = utf16_text;
- for (std::set<std::string>::iterator it = adapter_names.begin();
- it != adapter_names.end();
- ++it) {
- DhcpProxyScriptAdapterFetcher* fetcher(ImplCreateAdapterFetcher());
- fetcher->Fetch(*it, &fetcher_callback_);
- fetchers_.push_back(fetcher);
- }
- num_pending_fetchers_ = fetchers_.size();
+ worker_thread_ = ImplCreateWorkerThread(AsWeakPtr());
+ worker_thread_->Start();
return ERR_IO_PENDING;
}
@@ -113,6 +104,31 @@ void DhcpProxyScriptFetcherWin::CancelImpl() {
}
}
+void DhcpProxyScriptFetcherWin::OnGetCandidateAdapterNamesDone(
+ const std::set<std::string>& adapter_names) {
+ DCHECK(CalledOnValidThread());
+
+ // We may have been cancelled.
+ if (state_ != STATE_WAIT_ADAPTERS)
+ return;
+
+ state_ = STATE_NO_RESULTS;
+
+ if (adapter_names.empty()) {
+ TransitionToDone();
+ return;
+ }
+
+ for (std::set<std::string>::const_iterator it = adapter_names.begin();
+ it != adapter_names.end();
+ ++it) {
+ DhcpProxyScriptAdapterFetcher* fetcher(ImplCreateAdapterFetcher());
+ fetcher->Fetch(*it, &fetcher_callback_);
+ fetchers_.push_back(fetcher);
+ }
+ num_pending_fetchers_ = fetchers_.size();
+}
+
std::string DhcpProxyScriptFetcherWin::GetFetcherName() const {
DCHECK(CalledOnValidThread());
return "win";
@@ -175,33 +191,33 @@ void DhcpProxyScriptFetcherWin::OnWaitTimer() {
void DhcpProxyScriptFetcherWin::TransitionToDone() {
DCHECK(state_ == STATE_NO_RESULTS || state_ == STATE_SOME_RESULTS);
- // Should have returned immediately at Fetch() if no adapters to check.
- DCHECK(!fetchers_.empty());
-
- // Scan twice for the result; once through the whole list for success,
- // then if no success, return result for most preferred network adapter,
- // preferring "real" network errors to the ERR_PAC_NOT_IN_DHCP error.
- // Default to ERR_ABORTED if no fetcher completed.
- int result = ERR_ABORTED;
- for (FetcherVector::iterator it = fetchers_.begin();
- it != fetchers_.end();
- ++it) {
- if ((*it)->DidFinish() && (*it)->GetResult() == OK) {
- result = OK;
- *destination_string_ = (*it)->GetPacScript();
- pac_url_ = (*it)->GetPacURL();
- break;
- }
- }
- if (result != OK) {
- destination_string_->clear();
+ int result = ERR_PAC_NOT_IN_DHCP; // Default if no fetchers.
+ if (!fetchers_.empty()) {
+ // Scan twice for the result; once through the whole list for success,
+ // then if no success, return result for most preferred network adapter,
+ // preferring "real" network errors to the ERR_PAC_NOT_IN_DHCP error.
+ // Default to ERR_ABORTED if no fetcher completed.
+ result = ERR_ABORTED;
for (FetcherVector::iterator it = fetchers_.begin();
it != fetchers_.end();
++it) {
- if ((*it)->DidFinish()) {
- result = (*it)->GetResult();
- if (result != ERR_PAC_NOT_IN_DHCP) {
- break;
+ if ((*it)->DidFinish() && (*it)->GetResult() == OK) {
+ result = OK;
+ *destination_string_ = (*it)->GetPacScript();
+ pac_url_ = (*it)->GetPacURL();
+ break;
+ }
+ }
+ if (result != OK) {
+ destination_string_->clear();
+ for (FetcherVector::iterator it = fetchers_.begin();
+ it != fetchers_.end();
+ ++it) {
+ if ((*it)->DidFinish()) {
+ result = (*it)->GetResult();
+ if (result != ERR_PAC_NOT_IN_DHCP) {
+ break;
+ }
}
}
}
@@ -238,9 +254,10 @@ DhcpProxyScriptAdapterFetcher*
return new DhcpProxyScriptAdapterFetcher(url_request_context_);
}
-bool DhcpProxyScriptFetcherWin::ImplGetCandidateAdapterNames(
- std::set<std::string>* adapter_names) {
- return GetCandidateAdapterNames(adapter_names);
+DhcpProxyScriptFetcherWin::WorkerThread*
+ DhcpProxyScriptFetcherWin::ImplCreateWorkerThread(
+ const base::WeakPtr<DhcpProxyScriptFetcherWin>& owner) {
+ return new WorkerThread(owner);
}
int DhcpProxyScriptFetcherWin::ImplGetMaxWaitMs() {
@@ -313,4 +330,53 @@ bool DhcpProxyScriptFetcherWin::GetCandidateAdapterNames(
return true;
}
+DhcpProxyScriptFetcherWin::WorkerThread::WorkerThread(
+ const base::WeakPtr<DhcpProxyScriptFetcherWin>& owner) {
+ Init(owner);
+}
+
+DhcpProxyScriptFetcherWin::WorkerThread::~WorkerThread() {
+}
+
+void DhcpProxyScriptFetcherWin::WorkerThread::Start() {
+ bool succeeded = base::WorkerPool::PostTask(
+ FROM_HERE,
+ NewRunnableMethod(
+ this,
+ &DhcpProxyScriptFetcherWin::WorkerThread::ThreadFunc),
+ true);
+ DCHECK(succeeded);
+}
+
+void DhcpProxyScriptFetcherWin::WorkerThread::ThreadFunc() {
+ ImplGetCandidateAdapterNames(&adapter_names_);
+
+ bool succeeded = origin_loop_->PostTask(
+ FROM_HERE,
+ NewRunnableMethod(
+ this,
+ &DhcpProxyScriptFetcherWin::WorkerThread::OnThreadDone));
+ DCHECK(succeeded);
+}
+
+void DhcpProxyScriptFetcherWin::WorkerThread::OnThreadDone() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ if (owner_)
+ owner_->OnGetCandidateAdapterNamesDone(adapter_names_);
+}
+
+DhcpProxyScriptFetcherWin::WorkerThread::WorkerThread() {
+}
+
+void DhcpProxyScriptFetcherWin::WorkerThread::Init(
+ const base::WeakPtr<DhcpProxyScriptFetcherWin>& owner) {
+ owner_ = owner;
+ origin_loop_ = base::MessageLoopProxy::CreateForCurrentThread();
+}
+
+bool DhcpProxyScriptFetcherWin::WorkerThread::ImplGetCandidateAdapterNames(
+ std::set<std::string>* adapter_names) {
+ return DhcpProxyScriptFetcherWin::GetCandidateAdapterNames(adapter_names);
+}
+
} // namespace net