diff options
author | darin@google.com <darin@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-08-15 04:32:57 +0000 |
---|---|---|
committer | darin@google.com <darin@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-08-15 04:32:57 +0000 |
commit | 295039bdf97f08bf5c1c1c136dd977b7e97ddd31 (patch) | |
tree | ae3b47308e7d2f2db903f6a61c193e7a8c9ec882 /chrome/browser/automation | |
parent | 1c33790ef99bf8301260b9144110e71e7723d0f4 (diff) | |
download | chromium_src-295039bdf97f08bf5c1c1c136dd977b7e97ddd31.zip chromium_src-295039bdf97f08bf5c1c1c136dd977b7e97ddd31.tar.gz chromium_src-295039bdf97f08bf5c1c1c136dd977b7e97ddd31.tar.bz2 |
Introduce MessagePump to represent the native message pump used to drive a
MessageLoop. A MessageLoop now has a MessagePump.
This will make it possible to port the MessagePump interface to other platforms
as well as to use an IO completion port for our worker threads on Windows.
Currently, there is only MessagePumpWin, which attempts to preserve the
pre-existing behavior of the MessageLoop.
API changes to MessageLoop:
1. MessageLoop::Quit means return from Run when the MessageLoop would
otherwise wait for more work.
2. MessageLoop::Quit can no longer be called outside the context of an active Run
call. So, things like this:
MessageLoop::current()->Quit();
MessageLoop::current()->Run();
are now:
MessageLoop::current()->RunAllPending();
3. MessageLoop::Quit can no longer be called from other threads. This means that
PostTask(..., new MessageLoop::QuitTask()) must be used explicitly to Quit across
thread boundaries.
4. No protection is made to deal with nested MessageLoops involving watched
objects or APCs. In fact, an assertion is added to flag such cases. This is a
temporary measure until object watching and APC facilities are removed in favor
of a MessagePump designed around an IO completion port.
As part of this CL, I also changed the automation system to use an
IPC::ChannelProxy instead of an IPC::Channel. This moves the automation IPC
onto Chrome's IO thread where it belongs. I also fixed some abuses of
RefCounted in the AutomationProvider class. It was deleting itself in some
cases! This led to having to fix the ownership model for AutomationProvider,
which explains the changes to AutomationProviderList and so on.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@928 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/automation')
-rw-r--r-- | chrome/browser/automation/automation_provider.cc | 39 | ||||
-rw-r--r-- | chrome/browser/automation/automation_provider.h | 7 | ||||
-rw-r--r-- | chrome/browser/automation/automation_provider_list.cc | 8 |
3 files changed, 21 insertions, 33 deletions
diff --git a/chrome/browser/automation/automation_provider.cc b/chrome/browser/automation/automation_provider.cc index f23e7d1..d6e6b08 100644 --- a/chrome/browser/automation/automation_provider.cc +++ b/chrome/browser/automation/automation_provider.cc @@ -582,13 +582,8 @@ class DocumentPrintedNotificationObserver : public NotificationObserver { }; AutomationProvider::AutomationProvider(Profile* profile) - : connected_(false), - redirect_query_(0), + : redirect_query_(0), profile_(profile) { - AutomationProviderList* list = - g_browser_process->InitAutomationProviderList(); - DCHECK(NULL != list); - list->AddProvider(this); browser_tracker_.reset(new AutomationBrowserTracker(this)); window_tracker_.reset(new AutomationWindowTracker(this)); tab_tracker_.reset(new AutomationTabTracker(this)); @@ -601,21 +596,13 @@ AutomationProvider::AutomationProvider(Profile* profile) } AutomationProvider::~AutomationProvider() { - // TODO(vibhor) : Delete the pending observer objects. - AutomationProviderList* list = - g_browser_process->InitAutomationProviderList(); - DCHECK(NULL != list); - list->RemoveProvider(this); } void AutomationProvider::ConnectToChannel(const std::wstring& channel_id) { - scoped_ptr<IPC::Channel> channel( - new IPC::Channel(channel_id, IPC::Channel::MODE_CLIENT, this)); - connected_ = channel->Connect(); - if (connected_) { - channel_.swap(channel); - channel_->Send(new AutomationMsg_Hello(0)); - } + channel_.reset( + new IPC::ChannelProxy(channel_id, IPC::Channel::MODE_CLIENT, this, NULL, + g_browser_process->io_thread()->message_loop())); + channel_->Send(new AutomationMsg_Hello(0)); } void AutomationProvider::SetExpectedTabCount(size_t expected_tabs) { @@ -1450,7 +1437,7 @@ void AutomationProvider::HandleUnused(const IPC::Message& message, int handle) { void AutomationProvider::OnChannelError() { LOG(ERROR) << "AutomationProxy went away, shutting down app."; - delete this; + AutomationProviderList::GetInstance()->RemoveProvider(this); } // TODO(brettw) change this to accept GURLs when history supports it @@ -1478,11 +1465,8 @@ void AutomationProvider::OnRedirectQueryComplete( } bool AutomationProvider::Send(IPC::Message* msg) { - if (connected_) { - DCHECK(channel_.get()); - return channel_->Send(msg); - } - return false; + DCHECK(channel_.get()); + return channel_->Send(msg); } Browser* AutomationProvider::FindAndActivateTab( @@ -2235,7 +2219,8 @@ void TestingAutomationProvider::OnBrowserRemoving(const Browser* browser) { // last browser goes away. if (BrowserList::size() == 1) { // If you change this, update Observer for NOTIFY_SESSION_END below. - MessageLoop::current()->ReleaseSoon(FROM_HERE, this); + MessageLoop::current()->PostTask(FROM_HERE, + NewRunnableMethod(this, &TestingAutomationProvider::OnRemoveProvider)); } } @@ -2248,3 +2233,7 @@ void TestingAutomationProvider::Observe(NotificationType type, // Release balance out the Release scheduled by OnBrowserRemoving. Release(); } + +void TestingAutomationProvider::OnRemoveProvider() { + AutomationProviderList::GetInstance()->RemoveProvider(this); +} diff --git a/chrome/browser/automation/automation_provider.h b/chrome/browser/automation/automation_provider.h index 20f34a1..1bde370 100644 --- a/chrome/browser/automation/automation_provider.h +++ b/chrome/browser/automation/automation_provider.h @@ -47,7 +47,7 @@ #include "chrome/browser/automation/automation_autocomplete_edit_tracker.h" #include "chrome/browser/browser_list.h" #include "chrome/browser/history/history.h" -#include "chrome/common/ipc_channel.h" +#include "chrome/common/ipc_channel_proxy.h" #include "chrome/common/ipc_message.h" #include "chrome/common/notification_service.h" @@ -321,8 +321,7 @@ class AutomationProvider : public base::RefCounted<AutomationProvider>, typedef ObserverList<NotificationObserver> NotificationObserverList; typedef std::map<NavigationController*, LoginHandler*> LoginHandlerMap; - bool connected_; - scoped_ptr<IPC::Channel> channel_; + scoped_ptr<IPC::ChannelProxy> channel_; scoped_ptr<NotificationObserver> initial_load_observer_; scoped_ptr<NotificationObserver> new_tab_ui_load_observer_; scoped_ptr<NotificationObserver> find_in_page_observer_; @@ -383,5 +382,7 @@ class TestingAutomationProvider : public AutomationProvider, virtual void Observe(NotificationType type, const NotificationSource& source, const NotificationDetails& details); + + void OnRemoveProvider(); // Called via PostTask }; #endif // CHROME_BROWSER_AUTOMATION_AUTOMATION_PROVIDER_H_ diff --git a/chrome/browser/automation/automation_provider_list.cc b/chrome/browser/automation/automation_provider_list.cc index 4d9bb93..8d683d8 100644 --- a/chrome/browser/automation/automation_provider_list.cc +++ b/chrome/browser/automation/automation_provider_list.cc @@ -41,18 +41,15 @@ AutomationProviderList::AutomationProviderList() { AutomationProviderList::~AutomationProviderList() { iterator iter = automation_providers_.begin(); while (iter != automation_providers_.end()) { - AutomationProvider* provider = (*iter); - // Delete the entry first and update the iterator first because the d'tor - // of AutomationProvider will call RemoveProvider, making this iterator - // invalid + (*iter)->Release(); iter = automation_providers_.erase(iter); g_browser_process->ReleaseModule(); - delete provider; } instance_ = NULL; } bool AutomationProviderList::AddProvider(AutomationProvider* provider) { + provider->AddRef(); automation_providers_.push_back(provider); g_browser_process->AddRefModule(); return true; @@ -62,6 +59,7 @@ bool AutomationProviderList::RemoveProvider(AutomationProvider* provider) { const iterator remove_provider = find(automation_providers_.begin(), automation_providers_.end(), provider); if (remove_provider != automation_providers_.end()) { + (*remove_provider)->Release(); automation_providers_.erase(remove_provider); g_browser_process->ReleaseModule(); return true; |