diff options
author | darin@google.com <darin@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-08-26 05:53:57 +0000 |
---|---|---|
committer | darin@google.com <darin@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-08-26 05:53:57 +0000 |
commit | 4d9bdfafcd1393385860bc9fe947e0c07719c0f4 (patch) | |
tree | 67c91c3fa4c658352995e22b894535e60b04f282 /net | |
parent | 3c17b9c00d5fc28f5523ab60b0df502dd7c2a596 (diff) | |
download | chromium_src-4d9bdfafcd1393385860bc9fe947e0c07719c0f4.zip chromium_src-4d9bdfafcd1393385860bc9fe947e0c07719c0f4.tar.gz chromium_src-4d9bdfafcd1393385860bc9fe947e0c07719c0f4.tar.bz2 |
Allow consumers of MessageLoop to specify the type of MessageLoop they want.
This CL introduces a Type enum to MessageLoop, and I also created subclasses of MessageLoop corresponding to the non-default types: MessageLoopForIO and MessageLoopForUI.
I moved all of the platform-specific MessageLoop APIs onto either MessageLoopForIO or MessageLoopForUI. MessageLoopForIO gets the Watcher API, and MessageLoopForUI gets the Observer and Dispatcher APIs. Under the hood, both are implemented in terms of MessagePumpWin, but that will change in a future CL.
The Thread class is changed to allow the consumer to specify the Type of MessageLoop they want to have setup on the created thread.
I re-organized message_loop_unittest.cc and timer_unittest.cc so that I could exercise all (or most) of the tests against each type of MessageLoop.
Note: I know that "explicit MessageLoop(Type type = TYPE_DEFAULT);" is in violation to the style-guide's restriction against default arguments. I'm working on finding a decent solution to that problem. Please ignore this issue for now.
The corresponding chrome/ changes are coming in a separate CL due to Reitveld data size limitations.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@1362 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r-- | net/base/listen_socket_unittest.h | 4 | ||||
-rw-r--r-- | net/base/run_all_unittests.cc | 58 | ||||
-rw-r--r-- | net/build/net_unittests.vcproj | 2 | ||||
-rw-r--r-- | net/proxy/proxy_service.cc | 2 | ||||
-rw-r--r-- | net/proxy/proxy_service.h | 4 | ||||
-rw-r--r-- | net/url_request/url_request.cc | 7 | ||||
-rw-r--r-- | net/url_request/url_request_file_job.cc | 6 | ||||
-rw-r--r-- | net/url_request/url_request_file_job.h | 2 | ||||
-rw-r--r-- | net/url_request/url_request_unittest.h | 63 |
9 files changed, 122 insertions, 26 deletions
diff --git a/net/base/listen_socket_unittest.h b/net/base/listen_socket_unittest.h index 8c5cb6d..36af167 100644 --- a/net/base/listen_socket_unittest.h +++ b/net/base/listen_socket_unittest.h @@ -77,7 +77,7 @@ class ListenSocketTester : server_ = NULL; net::WinsockInit::Init(); - thread_.reset(new Thread("socketio_test")); + thread_.reset(new base::Thread("socketio_test")); thread_->Start(); loop_ = thread_->message_loop(); @@ -251,7 +251,7 @@ class ListenSocketTester : ASSERT_EQ(buf, HELLO_WORLD); } - scoped_ptr<Thread> thread_; + scoped_ptr<base::Thread> thread_; MessageLoop* loop_; ListenSocket* server_; ListenSocket* connection_; diff --git a/net/base/run_all_unittests.cc b/net/base/run_all_unittests.cc new file mode 100644 index 0000000..a1bae81 --- /dev/null +++ b/net/base/run_all_unittests.cc @@ -0,0 +1,58 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "base/message_loop.h" +#include "base/test_suite.h" + +class NetTestSuite : public TestSuite { + public: + NetTestSuite(int argc, char** argv) : TestSuite(argc, argv) { + } + + virtual void Initialize() { + TestSuite::Initialize(); + + message_loop_.reset(new MessageLoopForIO()); + } + + virtual void CleanUp() { + // We want to destroy this here before the TestSuite continues to tear down + // the environment. + message_loop_.reset(); + + TestSuite::Shutdown(); + } + + private: + scoped_ptr<MessageLoop> message_loop_; +}; + +int main(int argc, char** argv) { + return NetTestSuite(argc, argv).Run(); +} diff --git a/net/build/net_unittests.vcproj b/net/build/net_unittests.vcproj index 1619e5c..d1d720d 100644 --- a/net/build/net_unittests.vcproj +++ b/net/build/net_unittests.vcproj @@ -172,7 +172,7 @@ > </File> <File - RelativePath="..\..\base\run_all_unittests.cc" + RelativePath="..\base\run_all_unittests.cc" > </File> </Filter> diff --git a/net/proxy/proxy_service.cc b/net/proxy/proxy_service.cc index 1d48090..ec4fdd6 100644 --- a/net/proxy/proxy_service.cc +++ b/net/proxy/proxy_service.cc @@ -325,7 +325,7 @@ int ProxyService::ResolveProxy(const GURL& url, ProxyInfo* result, if (callback) { // Create PAC thread for asynchronous mode. if (!pac_thread_.get()) { - pac_thread_.reset(new Thread("pac-thread")); + pac_thread_.reset(new base::Thread("pac-thread")); pac_thread_->Start(); } } else { diff --git a/net/proxy/proxy_service.h b/net/proxy/proxy_service.h index 94e8235..5ca41e8 100644 --- a/net/proxy/proxy_service.h +++ b/net/proxy/proxy_service.h @@ -129,7 +129,7 @@ class ProxyService { friend class PacRequest; ProxyResolver* resolver() { return resolver_; } - Thread* pac_thread() { return pac_thread_.get(); } + base::Thread* pac_thread() { return pac_thread_.get(); } // Identifies the proxy configuration. ProxyConfig::ID config_id() const { return config_.id(); } @@ -151,7 +151,7 @@ class ProxyService { bool ShouldBypassProxyForURL(const GURL& url); ProxyResolver* resolver_; - scoped_ptr<Thread> pac_thread_; + scoped_ptr<base::Thread> pac_thread_; // We store the IE proxy config and a counter that is incremented each time // the config changes. diff --git a/net/url_request/url_request.cc b/net/url_request/url_request.cc index 6547e38..8c6d5f3 100644 --- a/net/url_request/url_request.cc +++ b/net/url_request/url_request.cc @@ -5,6 +5,7 @@ #include "net/url_request/url_request.h" #include "base/basictypes.h" +#include "base/message_loop.h" #include "base/process_util.h" #include "base/singleton.h" #include "base/stats_counters.h" @@ -47,6 +48,12 @@ URLRequest::URLRequest(const GURL& url, Delegate* delegate) URLREQUEST_COUNT_CTOR(); SIMPLE_STATS_COUNTER(L"URLRequestCount"); origin_pid_ = process_util::GetCurrentProcId(); + + // Sanity check out environment. + DCHECK(MessageLoop::current()) << + "The current MessageLoop must exist"; + DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()) << + "The current MessageLoop must be TYPE_IO"; } URLRequest::~URLRequest() { diff --git a/net/url_request/url_request_file_job.cc b/net/url_request/url_request_file_job.cc index 2ceaed3..4e23d78 100644 --- a/net/url_request/url_request_file_job.cc +++ b/net/url_request/url_request_file_job.cc @@ -140,7 +140,7 @@ void URLRequestFileJob::Start() { void URLRequestFileJob::Kill() { // If we are killed while waiting for an overlapped result... if (is_waiting_) { - MessageLoop::current()->WatchObject(overlapped_.hEvent, NULL); + MessageLoopForIO::current()->WatchObject(overlapped_.hEvent, NULL); is_waiting_ = false; Release(); } @@ -178,7 +178,7 @@ bool URLRequestFileJob::ReadRawData(char* dest, int dest_size, DWORD err = GetLastError(); if (err == ERROR_IO_PENDING) { // OK, wait for the object to become signaled - MessageLoop::current()->WatchObject(overlapped_.hEvent, this); + MessageLoopForIO::current()->WatchObject(overlapped_.hEvent, this); is_waiting_ = true; SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); AddRef(); @@ -261,7 +261,7 @@ void URLRequestFileJob::OnObjectSignaled(HANDLE object) { // We'll resume watching this handle if need be when we do // another IO. - MessageLoop::current()->WatchObject(object, NULL); + MessageLoopForIO::current()->WatchObject(object, NULL); is_waiting_ = false; DWORD bytes_read = 0; diff --git a/net/url_request/url_request_file_job.h b/net/url_request/url_request_file_job.h index f5999d3..638f4ff 100644 --- a/net/url_request/url_request_file_job.h +++ b/net/url_request/url_request_file_job.h @@ -14,7 +14,7 @@ // A request job that handles reading file URLs class URLRequestFileJob : public URLRequestJob, - protected MessageLoop::Watcher { + protected MessageLoopForIO::Watcher { public: URLRequestFileJob(URLRequest* request); virtual ~URLRequestFileJob(); diff --git a/net/url_request/url_request_unittest.h b/net/url_request/url_request_unittest.h index ea9b68e..f17e7fc 100644 --- a/net/url_request/url_request_unittest.h +++ b/net/url_request/url_request_unittest.h @@ -13,6 +13,8 @@ #include "base/path_service.h" #include "base/process_util.h" #include "base/string_util.h" +#include "base/thread.h" +#include "base/waitable_event.h" #include "net/base/net_errors.h" #include "net/http/http_network_layer.h" #include "net/url_request/url_request.h" @@ -113,7 +115,7 @@ class TestDelegate : public URLRequest::Delegate { request->Cancel(); } - void OnResponseCompleted(URLRequest* request) { + virtual void OnResponseCompleted(URLRequest* request) { if (quit_on_complete_) MessageLoop::current()->Quit(); } @@ -183,8 +185,7 @@ class TestDelegate : public URLRequest::Delegate { class TestServer : public process_util::ProcessFilter { public: TestServer(const std::wstring& document_root) - : context_(new TestURLRequestContext), - process_handle_(NULL), + : process_handle_(NULL), is_shutdown_(true) { Init(kDefaultHostName, kDefaultPort, document_root, std::wstring()); } @@ -213,16 +214,23 @@ class TestServer : public process_util::ProcessFilter { // A subclass may wish to send the request in a different manner virtual bool MakeGETRequest(const std::string& page_name) { - TestDelegate d; - URLRequest r(TestServerPage(page_name), &d); - r.set_context(context_); - r.set_method("GET"); - r.Start(); - EXPECT_TRUE(r.is_pending()); - - MessageLoop::current()->Run(); - - return r.status().is_success(); + const GURL& url = TestServerPage(page_name); + + // Spin up a background thread for this request so that we have access to + // an IO message loop, and in cases where this thread already has an IO + // message loop, we also want to avoid spinning a nested message loop. + + SyncTestDelegate d; + { + base::Thread io_thread("MakeGETRequest"); + base::Thread::Options options; + options.message_loop_type = MessageLoop::TYPE_IO; + io_thread.StartWithOptions(options); + io_thread.message_loop()->PostTask(FROM_HERE, NewRunnableFunction( + &TestServer::StartGETRequest, url, &d)); + d.Wait(); + } + return d.did_succeed(); } protected: @@ -232,8 +240,7 @@ class TestServer : public process_util::ProcessFilter { // constructed. The subclass should call Init once it is ready (usually in // its constructor). TestServer(ManualInit) - : context_(new TestURLRequestContext), - process_handle_(NULL), + : process_handle_(NULL), is_shutdown_(true) { } @@ -334,7 +341,31 @@ class TestServer : public process_util::ProcessFilter { } private: - scoped_refptr<TestURLRequestContext> context_; + // Used by MakeGETRequest to implement sync load behavior. + class SyncTestDelegate : public TestDelegate { + public: + SyncTestDelegate() : event_(false, false), success_(false) { + } + virtual void OnResponseCompleted(URLRequest* request) { + MessageLoop::current()->DeleteSoon(FROM_HERE, request); + success_ = request->status().is_success(); + event_.Signal(); + } + void Wait() { event_.Wait(); } + bool did_succeed() const { return success_; } + private: + base::WaitableEvent event_; + bool success_; + DISALLOW_COPY_AND_ASSIGN(SyncTestDelegate); + }; + static void StartGETRequest(const GURL& url, URLRequest::Delegate* delegate) { + URLRequest* request = new URLRequest(url, delegate); + request->set_context(new TestURLRequestContext()); + request->set_method("GET"); + request->Start(); + EXPECT_TRUE(request->is_pending()); + } + std::string base_address_; std::wstring python_runtime_; HANDLE process_handle_; |