| Index: net/proxy/sync_host_resolver_bridge_unittest.cc
|
| diff --git a/net/proxy/sync_host_resolver_bridge_unittest.cc b/net/proxy/sync_host_resolver_bridge_unittest.cc
|
| deleted file mode 100644
|
| index 81ec33ebec91f74fae4f719a655f9c810b97cae7..0000000000000000000000000000000000000000
|
| --- a/net/proxy/sync_host_resolver_bridge_unittest.cc
|
| +++ /dev/null
|
| @@ -1,244 +0,0 @@
|
| -// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "net/proxy/sync_host_resolver_bridge.h"
|
| -
|
| -#include "base/threading/thread.h"
|
| -#include "base/synchronization/waitable_event.h"
|
| -#include "net/base/address_list.h"
|
| -#include "net/base/net_errors.h"
|
| -#include "net/base/net_log.h"
|
| -#include "net/proxy/multi_threaded_proxy_resolver.h"
|
| -#include "net/base/test_completion_callback.h"
|
| -#include "net/proxy/proxy_info.h"
|
| -#include "testing/gtest/include/gtest/gtest.h"
|
| -
|
| -// TODO(eroman): This test should be moved into
|
| -// multi_threaded_proxy_resolver_unittest.cc.
|
| -
|
| -namespace net {
|
| -
|
| -namespace {
|
| -
|
| -// This implementation of HostResolver allows blocking until a resolve request
|
| -// has been received. The resolve requests it receives will never be completed.
|
| -class BlockableHostResolver : public HostResolver {
|
| - public:
|
| - BlockableHostResolver()
|
| - : event_(true, false),
|
| - was_request_cancelled_(false) {
|
| - }
|
| -
|
| - virtual int Resolve(const RequestInfo& info,
|
| - AddressList* addresses,
|
| - const CompletionCallback& callback,
|
| - RequestHandle* out_req,
|
| - const BoundNetLog& net_log) OVERRIDE {
|
| - EXPECT_FALSE(callback.is_null());
|
| - EXPECT_TRUE(out_req);
|
| - *out_req = reinterpret_cast<RequestHandle*>(1); // Magic value.
|
| -
|
| - // Indicate to the caller that a request was received.
|
| - event_.Signal();
|
| -
|
| - // We return ERR_IO_PENDING, as this request will NEVER be completed.
|
| - // Expectation is for the caller to later cancel the request.
|
| - return ERR_IO_PENDING;
|
| - }
|
| -
|
| - virtual int ResolveFromCache(const RequestInfo& info,
|
| - AddressList* addresses,
|
| - const BoundNetLog& net_log) OVERRIDE {
|
| - NOTIMPLEMENTED();
|
| - return ERR_UNEXPECTED;
|
| - }
|
| -
|
| - virtual void CancelRequest(RequestHandle req) OVERRIDE {
|
| - EXPECT_EQ(reinterpret_cast<RequestHandle*>(1), req);
|
| - was_request_cancelled_ = true;
|
| - }
|
| -
|
| - // Waits until Resolve() has been called.
|
| - void WaitUntilRequestIsReceived() {
|
| - event_.Wait();
|
| - }
|
| -
|
| - bool was_request_cancelled() const {
|
| - return was_request_cancelled_;
|
| - }
|
| -
|
| - private:
|
| - // Event to notify when a resolve request was received.
|
| - base::WaitableEvent event_;
|
| - bool was_request_cancelled_;
|
| -};
|
| -
|
| -// This implementation of ProxyResolver simply does a synchronous resolve
|
| -// on |host_resolver| in response to GetProxyForURL().
|
| -class SyncProxyResolver : public ProxyResolver {
|
| - public:
|
| - explicit SyncProxyResolver(SyncHostResolverBridge* host_resolver)
|
| - : ProxyResolver(false), host_resolver_(host_resolver) {}
|
| -
|
| - virtual int GetProxyForURL(const GURL& url,
|
| - ProxyInfo* results,
|
| - const CompletionCallback& callback,
|
| - RequestHandle* request,
|
| - const BoundNetLog& net_log) {
|
| - EXPECT_FALSE(!callback.is_null());
|
| - EXPECT_FALSE(request);
|
| -
|
| - // Do a synchronous host resolve.
|
| - HostResolver::RequestInfo info(HostPortPair::FromURL(url));
|
| - AddressList addresses;
|
| - int rv = host_resolver_->Resolve(info, &addresses, net_log);
|
| -
|
| - EXPECT_EQ(ERR_ABORTED, rv);
|
| -
|
| - return rv;
|
| - }
|
| -
|
| - virtual void CancelRequest(RequestHandle request) OVERRIDE {
|
| - NOTREACHED();
|
| - }
|
| -
|
| - virtual LoadState GetLoadState(RequestHandle request) const OVERRIDE {
|
| - NOTREACHED();
|
| - return LOAD_STATE_IDLE;
|
| - }
|
| -
|
| - virtual LoadState GetLoadStateThreadSafe(
|
| - RequestHandle request) const OVERRIDE {
|
| - NOTREACHED();
|
| - return LOAD_STATE_IDLE;
|
| - }
|
| -
|
| - virtual void Shutdown() OVERRIDE {
|
| - host_resolver_->Shutdown();
|
| - }
|
| -
|
| - virtual void CancelSetPacScript() OVERRIDE {
|
| - NOTREACHED();
|
| - }
|
| -
|
| - virtual int SetPacScript(
|
| - const scoped_refptr<ProxyResolverScriptData>& script_data,
|
| - const CompletionCallback& callback) OVERRIDE {
|
| - return OK;
|
| - }
|
| -
|
| - private:
|
| - SyncHostResolverBridge* const host_resolver_;
|
| -};
|
| -
|
| -class SyncProxyResolverFactory : public ProxyResolverFactory {
|
| - public:
|
| - // Takes ownership of |sync_host_resolver|.
|
| - explicit SyncProxyResolverFactory(SyncHostResolverBridge* sync_host_resolver)
|
| - : ProxyResolverFactory(false),
|
| - sync_host_resolver_(sync_host_resolver) {
|
| - }
|
| -
|
| - virtual ProxyResolver* CreateProxyResolver() OVERRIDE {
|
| - return new SyncProxyResolver(sync_host_resolver_.get());
|
| - }
|
| -
|
| - private:
|
| - const scoped_ptr<SyncHostResolverBridge> sync_host_resolver_;
|
| -};
|
| -
|
| -// This helper thread is used to create the circumstances for the deadlock.
|
| -// It is analagous to the "IO thread" which would be main thread running the
|
| -// network stack.
|
| -class IOThread : public base::Thread {
|
| - public:
|
| - IOThread() : base::Thread("IO-thread") {}
|
| -
|
| - virtual ~IOThread() {
|
| - Stop();
|
| - }
|
| -
|
| - BlockableHostResolver* async_resolver() {
|
| - return async_resolver_.get();
|
| - }
|
| -
|
| - protected:
|
| - virtual void Init() OVERRIDE {
|
| - async_resolver_.reset(new BlockableHostResolver());
|
| -
|
| - // Create a synchronous host resolver that operates the async host
|
| - // resolver on THIS thread.
|
| - SyncHostResolverBridge* sync_resolver =
|
| - new SyncHostResolverBridge(async_resolver_.get(), message_loop());
|
| -
|
| - proxy_resolver_.reset(
|
| - new MultiThreadedProxyResolver(
|
| - new SyncProxyResolverFactory(sync_resolver),
|
| - 1u));
|
| -
|
| - // Initialize the resolver.
|
| - TestCompletionCallback callback;
|
| - proxy_resolver_->SetPacScript(ProxyResolverScriptData::FromURL(GURL()),
|
| - callback.callback());
|
| - EXPECT_EQ(OK, callback.WaitForResult());
|
| -
|
| - // Start an asynchronous request to the proxy resolver
|
| - // (note that it will never complete).
|
| - proxy_resolver_->GetProxyForURL(
|
| - GURL("http://test/"), &results_, callback_.callback(), &request_,
|
| - BoundNetLog());
|
| - }
|
| -
|
| - virtual void CleanUp() OVERRIDE {
|
| - // Cancel the outstanding request (note however that this will not
|
| - // unblock the PAC thread though).
|
| - proxy_resolver_->CancelRequest(request_);
|
| -
|
| - // Delete the single threaded proxy resolver.
|
| - proxy_resolver_.reset();
|
| -
|
| - // (There may have been a completion posted back to origin thread, avoid
|
| - // leaking it by running).
|
| - MessageLoop::current()->RunUntilIdle();
|
| -
|
| - // During the teardown sequence of the single threaded proxy resolver,
|
| - // the outstanding host resolve should have been cancelled.
|
| - EXPECT_TRUE(async_resolver_->was_request_cancelled());
|
| - }
|
| -
|
| - private:
|
| - // This (async) host resolver will outlive the thread that is operating it
|
| - // synchronously.
|
| - scoped_ptr<BlockableHostResolver> async_resolver_;
|
| -
|
| - scoped_ptr<ProxyResolver> proxy_resolver_;
|
| -
|
| - // Data for the outstanding request to the single threaded proxy resolver.
|
| - TestCompletionCallback callback_;
|
| - ProxyInfo results_;
|
| - ProxyResolver::RequestHandle request_;
|
| -};
|
| -
|
| -// Test that a deadlock does not happen during shutdown when a host resolve
|
| -// is outstanding on the SyncHostResolverBridge.
|
| -// This is a regression test for http://crbug.com/41244.
|
| -TEST(MultiThreadedProxyResolverTest, ShutdownIsCalledBeforeThreadJoin) {
|
| - IOThread io_thread;
|
| - base::Thread::Options options;
|
| - options.message_loop_type = MessageLoop::TYPE_IO;
|
| - ASSERT_TRUE(io_thread.StartWithOptions(options));
|
| -
|
| - io_thread.async_resolver()->WaitUntilRequestIsReceived();
|
| -
|
| - // Now upon exitting this scope, the IOThread is destroyed -- this will
|
| - // stop the IOThread, which will in turn delete the
|
| - // SingleThreadedProxyResolver, which in turn will stop its internal
|
| - // PAC thread (which is currently blocked waiting on the host resolve which
|
| - // is running on IOThread). The IOThread::Cleanup() will verify that after
|
| - // the PAC thread is stopped, it cancels the request on the HostResolver.
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -} // namespace net
|
|
|