summaryrefslogtreecommitdiffstats
path: root/remoting
diff options
context:
space:
mode:
authorwez@chromium.org <wez@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-07 17:40:08 +0000
committerwez@chromium.org <wez@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-07 17:40:08 +0000
commitdd71eeb64f572b16552ed730676455fef635283e (patch)
treea7216339a5963260abc1a2d0cb5c6a4d35682b71 /remoting
parent01bf789e284b82c1163b1378e9ec73bedd19bad7 (diff)
downloadchromium_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.cc86
-rw-r--r--remoting/base/scoped_thread_proxy.h73
-rw-r--r--remoting/client/chromoting_client.cc15
-rw-r--r--remoting/client/chromoting_client.h6
-rw-r--r--remoting/client/plugin/chromoting_instance.cc72
-rw-r--r--remoting/client/plugin/chromoting_instance.h3
-rw-r--r--remoting/host/host_user_interface.cc30
-rw-r--r--remoting/host/host_user_interface.h8
-rw-r--r--remoting/host/it2me_host_user_interface.cc41
-rw-r--r--remoting/host/it2me_host_user_interface.h6
-rw-r--r--remoting/remoting.gyp2
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',
],