diff options
author | tim@chromium.org <tim@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-16 15:12:30 +0000 |
---|---|---|
committer | tim@chromium.org <tim@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-16 15:12:30 +0000 |
commit | 752889b65e7b57e81d26e0bbb1939944bc62c7a1 (patch) | |
tree | 466936a1985e27028e58d16bfb2dfdc62ab5f585 /chrome/browser | |
parent | e6af21855a279895ee1d28287c8606cd6fa87e21 (diff) | |
download | chromium_src-752889b65e7b57e81d26e0bbb1939944bc62c7a1.zip chromium_src-752889b65e7b57e81d26e0bbb1939944bc62c7a1.tar.gz chromium_src-752889b65e7b57e81d26e0bbb1939944bc62c7a1.tar.bz2 |
Change MediatorThreadImpl::Run to process messages forever and periodically call PumpAuxiliaryLoops to run the 3 (!!:(!!) other loops associated with this thread. There was previously a race where
quit would be called and set a cancellation flag before the posted task would
get executed.
BUG=37771
Review URL: http://codereview.chromium.org/984001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@41724 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r-- | chrome/browser/sync/engine/syncapi.cc | 6 | ||||
-rw-r--r-- | chrome/browser/sync/notifier/listener/mediator_thread_impl.cc | 44 | ||||
-rw-r--r-- | chrome/browser/sync/notifier/listener/mediator_thread_impl.h | 5 |
3 files changed, 38 insertions, 17 deletions
diff --git a/chrome/browser/sync/engine/syncapi.cc b/chrome/browser/sync/engine/syncapi.cc index 23243d5..a149a08 100644 --- a/chrome/browser/sync/engine/syncapi.cc +++ b/chrome/browser/sync/engine/syncapi.cc @@ -1485,11 +1485,13 @@ void SyncManager::SyncInternal::Shutdown() { } // Shutdown the xmpp buzz connection. - LOG(INFO) << "P2P: Mediator logout started."; if (talk_mediator()) { + LOG(INFO) << "P2P: Mediator logout started."; talk_mediator()->Logout(); + LOG(INFO) << "P2P: Mediator logout completed."; + talk_mediator_.reset(); + LOG(INFO) << "P2P: Mediator destroyed."; } - LOG(INFO) << "P2P: Mediator logout completed."; if (dir_manager()) { dir_manager()->FinalSaveChangesForAll(); diff --git a/chrome/browser/sync/notifier/listener/mediator_thread_impl.cc b/chrome/browser/sync/notifier/listener/mediator_thread_impl.cc index a6df235..11cf90a 100644 --- a/chrome/browser/sync/notifier/listener/mediator_thread_impl.cc +++ b/chrome/browser/sync/notifier/listener/mediator_thread_impl.cc @@ -59,20 +59,8 @@ void MediatorThreadImpl::Run() { socket_server->WakeUp(); #endif - do { -#if defined(OS_WIN) - ::MSG message; - if (::PeekMessage(&message, NULL, 0, 0, PM_REMOVE)) { - ::TranslateMessage(&message); - ::DispatchMessage(&message); - } -#endif - ProcessMessages(100); - if (pump_.get() && pump_->HasPendingTimeoutTask()) { - pump_->WakeTasks(); - } - MessageLoop::current()->RunAllPending(); - } while (!IsQuitting()); + Post(this, CMD_PUMP_AUXILIARY_LOOPS); + ProcessMessages(talk_base::kForever); #if defined(OS_WIN) set_socketserver(old_socket_server); @@ -80,11 +68,36 @@ void MediatorThreadImpl::Run() { #endif } +void MediatorThreadImpl::PumpAuxiliaryLoops() { +#if defined(OS_WIN) + ::MSG message; + if (::PeekMessage(&message, NULL, 0, 0, PM_REMOVE)) { + ::TranslateMessage(&message); + ::DispatchMessage(&message); + } +#endif + if (pump_.get() && pump_->HasPendingTimeoutTask()) { + pump_->WakeTasks(); + } + MessageLoop::current()->RunAllPending(); + // We want to pump auxiliary loops every 100ms until this thread is stopped, + // at which point this call will do nothing. + PostDelayed(100, this, CMD_PUMP_AUXILIARY_LOOPS); +} + void MediatorThreadImpl::Login(const buzz::XmppClientSettings& settings) { Post(this, CMD_LOGIN, new LoginData(settings)); } +void MediatorThreadImpl::Stop() { + Thread::Stop(); + CHECK(!login_.get() && !pump_.get()) << "Logout should be called prior to" + << "message queue exit."; +} + void MediatorThreadImpl::Logout() { + CHECK(!IsQuitting()) + << "Logout should be called prior to message queue exit."; Post(this, CMD_DISCONNECT); Stop(); } @@ -125,6 +138,9 @@ void MediatorThreadImpl::OnMessage(talk_base::Message* msg) { case CMD_SUBSCRIBE_FOR_UPDATES: DoSubscribeForUpdates(); break; + case CMD_PUMP_AUXILIARY_LOOPS: + PumpAuxiliaryLoops(); + break; default: LOG(ERROR) << "P2P: Someone passed a bad message to the thread."; break; diff --git a/chrome/browser/sync/notifier/listener/mediator_thread_impl.h b/chrome/browser/sync/notifier/listener/mediator_thread_impl.h index f8cf359..08b07cd 100644 --- a/chrome/browser/sync/notifier/listener/mediator_thread_impl.h +++ b/chrome/browser/sync/notifier/listener/mediator_thread_impl.h @@ -48,7 +48,8 @@ enum MEDIATOR_CMD { CMD_DISCONNECT, CMD_LISTEN_FOR_UPDATES, CMD_SEND_NOTIFICATION, - CMD_SUBSCRIBE_FOR_UPDATES + CMD_SUBSCRIBE_FOR_UPDATES, + CMD_PUMP_AUXILIARY_LOOPS, }; // Used to pass authentication information from the mediator to the thread. @@ -73,6 +74,7 @@ class MediatorThreadImpl // Start the thread. virtual void Start(); + virtual void Stop(); virtual void Run(); // These are called from outside threads, by the talk mediator object. @@ -94,6 +96,7 @@ class MediatorThreadImpl void DoListenForUpdates(); void DoSendNotification(); void DoStanzaLogging(); + void PumpAuxiliaryLoops(); // These handle messages indicating an event happened in the outside world. void OnUpdateListenerMessage(); |