diff options
author | wez@chromium.org <wez@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-07 17:40:08 +0000 |
---|---|---|
committer | wez@chromium.org <wez@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-07 17:40:08 +0000 |
commit | dd71eeb64f572b16552ed730676455fef635283e (patch) | |
tree | a7216339a5963260abc1a2d0cb5c6a4d35682b71 /remoting | |
parent | 01bf789e284b82c1163b1378e9ec73bedd19bad7 (diff) | |
download | chromium_src-dd71eeb64f572b16552ed730676455fef635283e.zip chromium_src-dd71eeb64f572b16552ed730676455fef635283e.tar.gz chromium_src-dd71eeb64f572b16552ed730676455fef635283e.tar.bz2 |
Replace ScopedThreadProxy with MessageLoopProxy & WeakPtrs.
This affects the following classes:
* ChromotingClient
* ChromotingInstance
* HostUserInterface
* It2MeHostUserInterface
The MessageLoopProxy/WeakPtr combination requires that the WeakPtr is created on the thread referred to by the proxy; code in which that is hard to arrange usually has subtle race-conditions.
This is a re-land of CL 1045404, replacing some CR_DEFINE_STATIC_LOCAL() instances with base::LazyInstance to avoid adding global initializers or finalizers.
TEST=Existing unit-tests, and manual testing.
Review URL: https://chromiumcodereview.appspot.com/10440107
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@141028 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting')
-rw-r--r-- | remoting/base/scoped_thread_proxy.cc | 86 | ||||
-rw-r--r-- | remoting/base/scoped_thread_proxy.h | 73 | ||||
-rw-r--r-- | remoting/client/chromoting_client.cc | 15 | ||||
-rw-r--r-- | remoting/client/chromoting_client.h | 6 | ||||
-rw-r--r-- | remoting/client/plugin/chromoting_instance.cc | 72 | ||||
-rw-r--r-- | remoting/client/plugin/chromoting_instance.h | 3 | ||||
-rw-r--r-- | remoting/host/host_user_interface.cc | 30 | ||||
-rw-r--r-- | remoting/host/host_user_interface.h | 8 | ||||
-rw-r--r-- | remoting/host/it2me_host_user_interface.cc | 41 | ||||
-rw-r--r-- | remoting/host/it2me_host_user_interface.h | 6 | ||||
-rw-r--r-- | remoting/remoting.gyp | 2 |
11 files changed, 92 insertions, 250 deletions
diff --git a/remoting/base/scoped_thread_proxy.cc b/remoting/base/scoped_thread_proxy.cc deleted file mode 100644 index d1dcc26..0000000 --- a/remoting/base/scoped_thread_proxy.cc +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright (c) 2011 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 "remoting/base/scoped_thread_proxy.h" - -#include "base/bind.h" - -namespace remoting { - -class ScopedThreadProxy::Core : public base::RefCountedThreadSafe<Core> { - public: - Core(base::MessageLoopProxy* message_loop) - : message_loop_(message_loop), - canceled_(false) { - } - - void PostTask(const tracked_objects::Location& from_here, - const base::Closure& closure) { - if (!canceled_) - message_loop_->PostTask(from_here, Wrap(closure)); - } - - void PostDelayedTask( - const tracked_objects::Location& from_here, - const base::Closure& closure, - int64 delay_ms) { - if (!canceled_) { - message_loop_->PostDelayedTask(from_here, Wrap(closure), delay_ms); - } - } - - void Detach() { - DCHECK(message_loop_->BelongsToCurrentThread()); - canceled_ = true; - } - - private: - friend class base::RefCountedThreadSafe<Core>; - - ~Core() { - DCHECK(canceled_); - } - - base::Closure Wrap(const base::Closure& closure) { - return base::Bind(&Core::CallClosure, this, closure); - } - - void CallClosure(const base::Closure& closure) { - DCHECK(message_loop_->BelongsToCurrentThread()); - - if (!canceled_) - closure.Run(); - } - - scoped_refptr<base::MessageLoopProxy> message_loop_; - bool canceled_; - - DISALLOW_COPY_AND_ASSIGN(Core); -}; - -ScopedThreadProxy::ScopedThreadProxy(base::MessageLoopProxy* message_loop) - : core_(new Core(message_loop)) { -} - -ScopedThreadProxy::~ScopedThreadProxy() { - Detach(); -} - -void ScopedThreadProxy::PostTask(const tracked_objects::Location& from_here, - const base::Closure& closure) { - core_->PostTask(from_here, closure); -} - -void ScopedThreadProxy::PostDelayedTask( - const tracked_objects::Location& from_here, - const base::Closure& closure, - int64 delay_ms) { - core_->PostDelayedTask(from_here, closure, delay_ms); -} - -void ScopedThreadProxy::Detach() { - core_->Detach(); -} - -} // namespace remoting diff --git a/remoting/base/scoped_thread_proxy.h b/remoting/base/scoped_thread_proxy.h deleted file mode 100644 index 9e43a15..0000000 --- a/remoting/base/scoped_thread_proxy.h +++ /dev/null @@ -1,73 +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. - -#ifndef REMOTING_BASE_SCOPED_THREAD_PROXY_H_ -#define REMOTING_BASE_SCOPED_THREAD_PROXY_H_ - -#include "base/callback_forward.h" -#include "base/message_loop_proxy.h" - -namespace remoting { - -// ScopedThreadProxy is proxy for message loops that cancels all -// pending tasks when it is destroyed. It can be used to post tasks -// for a non-refcounted object. Must be deleted on the thread it -// belongs to. -// -// -// The main difference from WeakPtr<> is that this class can be used safely to -// post tasks from different threads. -// It is similar to WeakHandle<> used in sync: the main difference is -// that WeakHandle<> creates closures itself, while ScopedThreadProxy -// accepts base::Closure instances which caller needs to create using -// base::Bind(). -// -// TODO(sergeyu): Potentially we could use WeakHandle<> instead of -// this class. Consider migrating to WeakHandle<> when it is moved to -// src/base and support for delayed tasks is implemented. -// -// Usage: -// class MyClass { -// public: -// MyClass() -// : thread_proxy_(base::MessageLoopProxy::current()) {} -// -// // Always called on the thread on which this object was created. -// void NonThreadSafeMethod() {} -// -// // Can be called on any thread. -// void ThreadSafeMethod() { -// thread_proxy_.PostTask(FROM_HERE, base::Bind( -// &MyClass::NonThreadSafeMethod, base::Unretained(this))); -// } -// -// private: -// ScopedThreadProxy thread_proxy_; -// }; -class ScopedThreadProxy { - public: - ScopedThreadProxy(base::MessageLoopProxy* message_loop); - ~ScopedThreadProxy(); - - void PostTask(const tracked_objects::Location& from_here, - const base::Closure& closure); - void PostDelayedTask(const tracked_objects::Location& from_here, - const base::Closure& closure, - int64 delay_ms); - - // Cancels all tasks posted via this proxy. Must be called on the - // thread this object belongs to. - void Detach(); - - private: - class Core; - - scoped_refptr<Core> core_; - - DISALLOW_COPY_AND_ASSIGN(ScopedThreadProxy); -}; - -} // namespace remoting - -#endif // REMOTING_BASE_SCOPED_THREAD_PROXY_H_ diff --git a/remoting/client/chromoting_client.cc b/remoting/client/chromoting_client.cc index a28b887..a545244 100644 --- a/remoting/client/chromoting_client.cc +++ b/remoting/client/chromoting_client.cc @@ -40,7 +40,7 @@ ChromotingClient::ChromotingClient(const ClientConfig& config, client_done_(client_done), packet_being_processed_(false), last_sequence_number_(0), - thread_proxy_(context_->network_message_loop()) { + weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { } ChromotingClient::~ChromotingClient() { @@ -56,6 +56,9 @@ void ChromotingClient::Start( config_.authentication_tag, config_.shared_secret, config_.authentication_methods)); + // Create a WeakPtr to ourself for to use for all posted tasks. + weak_ptr_ = weak_factory_.GetWeakPtr(); + connection_->Connect(xmpp_proxy, config_.local_jid, config_.host_jid, config_.host_public_key, transport_factory.Pass(), authenticator.Pass(), this, this, this, this); @@ -69,7 +72,7 @@ void ChromotingClient::Stop(const base::Closure& shutdown_task) { if (!message_loop()->BelongsToCurrentThread()) { message_loop()->PostTask( FROM_HERE, base::Bind(&ChromotingClient::Stop, - base::Unretained(this), shutdown_task)); + weak_ptr_, shutdown_task)); return; } @@ -81,7 +84,7 @@ void ChromotingClient::Stop(const base::Closure& shutdown_task) { } connection_->Disconnect(base::Bind(&ChromotingClient::OnDisconnected, - base::Unretained(this), shutdown_task)); + weak_ptr_, shutdown_task)); } void ChromotingClient::OnDisconnected(const base::Closure& shutdown_task) { @@ -191,7 +194,7 @@ base::MessageLoopProxy* ChromotingClient::message_loop() { void ChromotingClient::OnPacketDone(bool last_packet, base::Time decode_start) { if (!message_loop()->BelongsToCurrentThread()) { - thread_proxy_.PostTask(FROM_HERE, base::Bind( + message_loop()->PostTask(FROM_HERE, base::Bind( &ChromotingClient::OnPacketDone, base::Unretained(this), last_packet, decode_start)); return; @@ -215,8 +218,8 @@ void ChromotingClient::OnPacketDone(bool last_packet, void ChromotingClient::Initialize() { if (!message_loop()->BelongsToCurrentThread()) { - thread_proxy_.PostTask(FROM_HERE, base::Bind( - &ChromotingClient::Initialize, base::Unretained(this))); + message_loop()->PostTask(FROM_HERE, base::Bind( + &ChromotingClient::Initialize, weak_ptr_)); return; } diff --git a/remoting/client/chromoting_client.h b/remoting/client/chromoting_client.h index bbb8a48..6856a20 100644 --- a/remoting/client/chromoting_client.h +++ b/remoting/client/chromoting_client.h @@ -10,8 +10,8 @@ #include <list> #include "base/callback.h" +#include "base/memory/weak_ptr.h" #include "base/time.h" -#include "remoting/base/scoped_thread_proxy.h" #include "remoting/client/client_config.h" #include "remoting/client/chromoting_stats.h" #include "remoting/client/chromoting_view.h" @@ -124,7 +124,9 @@ class ChromotingClient : public protocol::ConnectionToHost::HostEventCallback, // Keep track of the last sequence number bounced back from the host. int64 last_sequence_number_; - ScopedThreadProxy thread_proxy_; + // WeakPtr used to avoid tasks accessing the client after it is deleted. + base::WeakPtrFactory<ChromotingClient> weak_factory_; + base::WeakPtr<ChromotingClient> weak_ptr_; DISALLOW_COPY_AND_ASSIGN(ChromotingClient); }; diff --git a/remoting/client/plugin/chromoting_instance.cc b/remoting/client/plugin/chromoting_instance.cc index 808dd84..8435e1e 100644 --- a/remoting/client/plugin/chromoting_instance.cc +++ b/remoting/client/plugin/chromoting_instance.cc @@ -91,18 +91,20 @@ std::string ConnectionErrorToString(ChromotingInstance::ConnectionError error) { return ""; } -} // namespace - // This flag blocks LOGs to the UI if we're already in the middle of logging // to the UI. This prevents a potential infinite loop if we encounter an error // while sending the log message to the UI. -static bool g_logging_to_plugin = false; -static bool g_has_logging_instance = false; -static ChromotingInstance* g_logging_instance = NULL; -static logging::LogMessageHandlerFunction g_logging_old_handler = NULL; - -static base::LazyInstance<base::Lock>::Leaky +bool g_logging_to_plugin = false; +bool g_has_logging_instance = false; +base::LazyInstance<scoped_refptr<base::SingleThreadTaskRunner> >::Leaky + g_logging_task_runner = LAZY_INSTANCE_INITIALIZER; +base::LazyInstance<base::WeakPtr<ChromotingInstance> >::Leaky + g_logging_instance = LAZY_INSTANCE_INITIALIZER; +base::LazyInstance<base::Lock>::Leaky g_logging_lock = LAZY_INSTANCE_INITIALIZER; +logging::LogMessageHandlerFunction g_logging_old_handler = NULL; + +} // namespace // String sent in the "hello" message to the plugin to describe features. const char ChromotingInstance::kApiFeatures[] = @@ -134,7 +136,7 @@ ChromotingInstance::ChromotingInstance(PP_Instance pp_instance) plugin_message_loop_( new PluginMessageLoopProxy(&plugin_thread_delegate_)), context_(plugin_message_loop_), - thread_proxy_(new ScopedThreadProxy(plugin_message_loop_)) { + weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE | PP_INPUTEVENT_CLASS_WHEEL); RequestFilteringInputEvents(PP_INPUTEVENT_CLASS_KEYBOARD); @@ -152,10 +154,6 @@ ChromotingInstance::ChromotingInstance(PP_Instance pp_instance) ChromotingInstance::~ChromotingInstance() { DCHECK(plugin_message_loop_->BelongsToCurrentThread()); - // Detach the log proxy so we don't log anything else to the UI. - // This needs to be done before the instance is unregistered for logging. - thread_proxy_->Detach(); - // Unregister this instance so that debug log messages will no longer be sent // to it. This will stop all logging in all Chromoting instances. UnregisterLoggingInstance(); @@ -170,10 +168,7 @@ ChromotingInstance::~ChromotingInstance() { // Stopping the context shuts down all chromoting threads. context_.Stop(); - // Delete |thread_proxy_| before we detach |plugin_message_loop_|, - // otherwise ScopedThreadProxy may DCHECK when being destroyed. - thread_proxy_.reset(); - + // Ensure that nothing touches the plugin thread delegate after this point. plugin_message_loop_->Detach(); } @@ -625,7 +620,8 @@ void ChromotingInstance::RegisterLoggingInstance() { // and display them to the user. // If multiple plugins are run, then the last one registered will handle all // logging for all instances. - g_logging_instance = this; + g_logging_instance.Get() = weak_factory_.GetWeakPtr(); + g_logging_task_runner.Get() = plugin_message_loop_; g_has_logging_instance = true; } @@ -633,12 +629,13 @@ void ChromotingInstance::UnregisterLoggingInstance() { base::AutoLock lock(g_logging_lock.Get()); // Don't unregister unless we're the currently registered instance. - if (this != g_logging_instance) + if (this != g_logging_instance.Get().get()) return; // Unregister this instance for logging. g_has_logging_instance = false; - g_logging_instance = NULL; + g_logging_instance.Get().reset(); + g_logging_task_runner.Get() = NULL; VLOG(1) << "Unregistering global log handler"; } @@ -660,24 +657,28 @@ bool ChromotingInstance::LogToUI(int severity, const char* file, int line, // the lock and check |g_logging_instance| unnecessarily. This is not // problematic because we always set |g_logging_instance| inside a lock. if (g_has_logging_instance) { - // Do not LOG anything while holding this lock or else the code will - // deadlock while trying to re-get the lock we're already in. - base::AutoLock lock(g_logging_lock.Get()); - if (g_logging_instance && - // If |g_logging_to_plugin| is set and we're on the logging thread, then - // this LOG message came from handling a previous LOG message and we - // should skip it to avoid an infinite loop of LOG messages. - // We don't have a lock around |g_in_processtoui|, but that's OK since - // the value is only read/written on the logging thread. - (!g_logging_instance->plugin_message_loop_->BelongsToCurrentThread() || - !g_logging_to_plugin)) { + scoped_refptr<base::SingleThreadTaskRunner> logging_task_runner; + base::WeakPtr<ChromotingInstance> logging_instance; + + { + base::AutoLock lock(g_logging_lock.Get()); + // If we're on the logging thread and |g_logging_to_plugin| is set then + // this LOG message came from handling a previous LOG message and we + // should skip it to avoid an infinite loop of LOG messages. + if (!g_logging_task_runner.Get()->BelongsToCurrentThread() || + !g_logging_to_plugin) { + logging_task_runner = g_logging_task_runner.Get(); + logging_instance = g_logging_instance.Get(); + } + } + + if (logging_task_runner.get()) { std::string message = remoting::GetTimestampString(); message += (str.c_str() + message_start); - // |thread_proxy_| is safe to use here because we detach it before - // tearing down the |g_logging_instance|. - g_logging_instance->thread_proxy_->PostTask( + + logging_task_runner->PostTask( FROM_HERE, base::Bind(&ChromotingInstance::ProcessLogToUI, - base::Unretained(g_logging_instance), message)); + logging_instance, message)); } } @@ -692,6 +693,7 @@ void ChromotingInstance::ProcessLogToUI(const std::string& message) { // This flag (which is set only here) is used to prevent LogToUI from posting // new tasks while we're in the middle of servicing a LOG call. This can // happen if the call to LogDebugInfo tries to LOG anything. + // Since it is read on the plugin thread, we don't need to lock to set it. g_logging_to_plugin = true; scoped_ptr<base::DictionaryValue> data(new base::DictionaryValue()); data->SetString("message", message); diff --git a/remoting/client/plugin/chromoting_instance.h b/remoting/client/plugin/chromoting_instance.h index dc8f549..5c8fa487 100644 --- a/remoting/client/plugin/chromoting_instance.h +++ b/remoting/client/plugin/chromoting_instance.h @@ -25,7 +25,6 @@ #endif #include "ppapi/cpp/instance.h" -#include "remoting/base/scoped_thread_proxy.h" #include "remoting/client/client_context.h" #include "remoting/client/key_event_mapper.h" #include "remoting/client/plugin/mac_key_event_processor.h" @@ -220,7 +219,7 @@ class ChromotingInstance : // connection. scoped_refptr<PepperXmppProxy> xmpp_proxy_; - scoped_ptr<ScopedThreadProxy> thread_proxy_; + base::WeakPtrFactory<ChromotingInstance> weak_factory_; DISALLOW_COPY_AND_ASSIGN(ChromotingInstance); }; diff --git a/remoting/host/host_user_interface.cc b/remoting/host/host_user_interface.cc index 4401fb5..964473b 100644 --- a/remoting/host/host_user_interface.cc +++ b/remoting/host/host_user_interface.cc @@ -16,7 +16,8 @@ HostUserInterface::HostUserInterface(ChromotingHostContext* context) : host_(NULL), context_(context), is_monitoring_local_inputs_(false), - ui_thread_proxy_(context->ui_message_loop()) { + ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), + weak_ptr_(weak_factory_.GetWeakPtr()) { } HostUserInterface::~HostUserInterface() { @@ -24,8 +25,6 @@ HostUserInterface::~HostUserInterface() { MonitorLocalInputs(false); ShowDisconnectWindow(false, std::string()); - - ui_thread_proxy_.Detach(); } void HostUserInterface::Start(ChromotingHost* host, @@ -42,19 +41,23 @@ void HostUserInterface::Start(ChromotingHost* host, } void HostUserInterface::OnClientAuthenticated(const std::string& jid) { + DCHECK(network_message_loop()->BelongsToCurrentThread()); + authenticated_jid_ = jid; std::string username = jid.substr(0, jid.find('/')); - ui_thread_proxy_.PostTask(FROM_HERE, base::Bind( + ui_message_loop()->PostTask(FROM_HERE, base::Bind( &HostUserInterface::ProcessOnClientAuthenticated, - base::Unretained(this), username)); + weak_ptr_, username)); } void HostUserInterface::OnClientDisconnected(const std::string& jid) { + DCHECK(network_message_loop()->BelongsToCurrentThread()); + if (jid == authenticated_jid_) { - ui_thread_proxy_.PostTask(FROM_HERE, base::Bind( + ui_message_loop()->PostTask(FROM_HERE, base::Bind( &HostUserInterface::ProcessOnClientDisconnected, - base::Unretained(this))); + weak_ptr_)); } } @@ -62,20 +65,20 @@ void HostUserInterface::OnAccessDenied(const std::string& jid) { } void HostUserInterface::OnShutdown() { + DCHECK(network_message_loop()->BelongsToCurrentThread()); + // Host status observers must be removed on the network thread, so // it must happen here instead of in the destructor. host_->RemoveStatusObserver(this); host_ = NULL; - disconnect_callback_ = base::Closure(); } void HostUserInterface::OnDisconnectCallback() { DCHECK(ui_message_loop()->BelongsToCurrentThread()); - DCHECK(!disconnect_callback_.is_null()); MonitorLocalInputs(false); ShowDisconnectWindow(false, std::string()); - disconnect_callback_.Run(); + DisconnectSession(); } base::MessageLoopProxy* HostUserInterface::network_message_loop() const { @@ -86,7 +89,10 @@ base::MessageLoopProxy* HostUserInterface::ui_message_loop() const { } void HostUserInterface::DisconnectSession() const { - return disconnect_callback_.Run(); + DCHECK(ui_message_loop()->BelongsToCurrentThread()); + DCHECK(!disconnect_callback_.is_null()); + + disconnect_callback_.Run(); } void HostUserInterface::ProcessOnClientAuthenticated( @@ -140,7 +146,7 @@ void HostUserInterface::ShowDisconnectWindow(bool show, disconnect_window_->Show( host_, base::Bind(&HostUserInterface::OnDisconnectCallback, - base::Unretained(this)), + weak_ptr_), username); } else { disconnect_window_->Hide(); diff --git a/remoting/host/host_user_interface.h b/remoting/host/host_user_interface.h index 9c2729e..942cd2a 100644 --- a/remoting/host/host_user_interface.h +++ b/remoting/host/host_user_interface.h @@ -11,8 +11,8 @@ #include "base/callback.h" #include "base/compiler_specific.h" #include "base/memory/scoped_ptr.h" - -#include "remoting/base/scoped_thread_proxy.h" +#include "base/memory/weak_ptr.h" +#include "base/message_loop_proxy.h" #include "remoting/host/host_status_observer.h" namespace remoting { @@ -95,7 +95,9 @@ class HostUserInterface : public HostStatusObserver { bool is_monitoring_local_inputs_; - ScopedThreadProxy ui_thread_proxy_; + // WeakPtr used to avoid tasks accessing the client after it is deleted. + base::WeakPtrFactory<HostUserInterface> weak_factory_; + base::WeakPtr<HostUserInterface> weak_ptr_; DISALLOW_COPY_AND_ASSIGN(HostUserInterface); }; diff --git a/remoting/host/it2me_host_user_interface.cc b/remoting/host/it2me_host_user_interface.cc index c39f6d3..1b2f392 100644 --- a/remoting/host/it2me_host_user_interface.cc +++ b/remoting/host/it2me_host_user_interface.cc @@ -24,29 +24,15 @@ static const int kContinueWindowHideTimeoutMs = 60 * 1000; namespace remoting { -class It2MeHostUserInterface::TimerTask { - public: - TimerTask(base::MessageLoopProxy* message_loop, - const base::Closure& task, - int delay_ms) - : thread_proxy_(message_loop) { - thread_proxy_.PostDelayedTask(FROM_HERE, task, delay_ms); - } - - private: - ScopedThreadProxy thread_proxy_; -}; - - It2MeHostUserInterface::It2MeHostUserInterface(ChromotingHostContext* context) - : HostUserInterface(context) { + : HostUserInterface(context), + ALLOW_THIS_IN_INITIALIZER_LIST(timer_weak_factory_(this)) { } It2MeHostUserInterface::~It2MeHostUserInterface() { DCHECK(ui_message_loop()->BelongsToCurrentThread()); ShowContinueWindow(false); - StartContinueWindowTimer(false); } void It2MeHostUserInterface::Start(ChromotingHost* host, @@ -103,7 +89,6 @@ void It2MeHostUserInterface::ContinueSession(bool continue_session) { if (continue_session) { get_host()->PauseSession(false); - timer_task_.reset(); StartContinueWindowTimer(true); } else { DisconnectSession(); @@ -116,11 +101,13 @@ void It2MeHostUserInterface::OnContinueWindowTimer() { get_host()->PauseSession(true); ShowContinueWindow(true); - timer_task_.reset(new TimerTask( - ui_message_loop(), + // Cancel any pending timer and post one to hide the continue window. + timer_weak_factory_.InvalidateWeakPtrs(); + ui_message_loop()->PostDelayedTask( + FROM_HERE, base::Bind(&It2MeHostUserInterface::OnShutdownHostTimer, - base::Unretained(this)), - kContinueWindowHideTimeoutMs)); + timer_weak_factory_.GetWeakPtr()), + kContinueWindowHideTimeoutMs); } void It2MeHostUserInterface::OnShutdownHostTimer() { @@ -144,14 +131,14 @@ void It2MeHostUserInterface::ShowContinueWindow(bool show) { void It2MeHostUserInterface::StartContinueWindowTimer(bool start) { DCHECK(ui_message_loop()->BelongsToCurrentThread()); + // Abandon previous timer events by invalidating their weak pointer to us. + timer_weak_factory_.InvalidateWeakPtrs(); if (start) { - timer_task_.reset(new TimerTask( - ui_message_loop(), + ui_message_loop()->PostDelayedTask( + FROM_HERE, base::Bind(&It2MeHostUserInterface::OnContinueWindowTimer, - base::Unretained(this)), - kContinueWindowShowTimeoutMs)); - } else { - timer_task_.reset(); + timer_weak_factory_.GetWeakPtr()), + kContinueWindowShowTimeoutMs); } } diff --git a/remoting/host/it2me_host_user_interface.h b/remoting/host/it2me_host_user_interface.h index b054c65..71619ea 100644 --- a/remoting/host/it2me_host_user_interface.h +++ b/remoting/host/it2me_host_user_interface.h @@ -11,6 +11,7 @@ #include "base/callback.h" #include "base/compiler_specific.h" #include "base/memory/scoped_ptr.h" +#include "base/memory/weak_ptr.h" #include "remoting/host/host_user_interface.h" @@ -67,8 +68,9 @@ class It2MeHostUserInterface : public HostUserInterface { // the connection. scoped_ptr<ContinueWindow> continue_window_; - // Timer controlling the "continue session" dialog. - scoped_ptr<TimerTask> timer_task_; + // Weak pointer factory used to abandon the "continue session" timer when + // hiding the "continue session" dialog, or tearing down the IT2Me UI. + base::WeakPtrFactory<It2MeHostUserInterface> timer_weak_factory_; DISALLOW_COPY_AND_ASSIGN(It2MeHostUserInterface); }; diff --git a/remoting/remoting.gyp b/remoting/remoting.gyp index 0db3c18..cd1cd40 100644 --- a/remoting/remoting.gyp +++ b/remoting/remoting.gyp @@ -1040,8 +1040,6 @@ 'base/rate_counter.h', 'base/running_average.cc', 'base/running_average.h', - 'base/scoped_thread_proxy.cc', - 'base/scoped_thread_proxy.h', 'base/util.cc', 'base/util.h', ], |