diff options
Diffstat (limited to 'remoting')
-rw-r--r-- | remoting/base/plugin_message_loop_proxy.cc | 114 | ||||
-rw-r--r-- | remoting/base/plugin_message_loop_proxy.h | 79 | ||||
-rw-r--r-- | remoting/host/chromoting_host_context.cc | 37 | ||||
-rw-r--r-- | remoting/host/chromoting_host_context.h | 22 | ||||
-rw-r--r-- | remoting/host/chromoting_host_context_unittest.cc | 6 | ||||
-rw-r--r-- | remoting/host/chromoting_host_unittest.cc | 8 | ||||
-rw-r--r-- | remoting/host/desktop_environment.cc | 48 | ||||
-rw-r--r-- | remoting/host/host_mock_objects.cc | 6 | ||||
-rw-r--r-- | remoting/host/host_mock_objects.h | 2 | ||||
-rw-r--r-- | remoting/host/plugin/host_plugin.cc | 53 | ||||
-rw-r--r-- | remoting/host/plugin/host_script_object.cc | 50 | ||||
-rw-r--r-- | remoting/host/plugin/host_script_object.h | 13 | ||||
-rw-r--r-- | remoting/host/simple_host_process.cc | 9 | ||||
-rw-r--r-- | remoting/remoting.gyp | 2 |
14 files changed, 133 insertions, 316 deletions
diff --git a/remoting/base/plugin_message_loop_proxy.cc b/remoting/base/plugin_message_loop_proxy.cc deleted file mode 100644 index 0f6c668..0000000 --- a/remoting/base/plugin_message_loop_proxy.cc +++ /dev/null @@ -1,114 +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/plugin_message_loop_proxy.h" - -namespace remoting { - -PluginMessageLoopProxy::PluginMessageLoopProxy(Delegate* delegate) - : delegate_(delegate) { -} - -PluginMessageLoopProxy::~PluginMessageLoopProxy() { -} - -void PluginMessageLoopProxy::Detach() { - base::AutoLock auto_lock(lock_); - delegate_ = NULL; -} - -// MessageLoopProxy interface implementation. -bool PluginMessageLoopProxy::PostTask( - const tracked_objects::Location& from_here, - Task* task) { - return PostDelayedTask(from_here, task, 0); -} - -bool PluginMessageLoopProxy::PostDelayedTask( - const tracked_objects::Location& from_here, - Task* task, - int64 delay_ms) { - base::AutoLock auto_lock(lock_); - if (!delegate_) { - return false; - } else { - return delegate_->RunOnPluginThread( - delay_ms, &PluginMessageLoopProxy::RunTask, task); - } -} - -bool PluginMessageLoopProxy::PostNonNestableTask( - const tracked_objects::Location& from_here, - Task* task) { - // All tasks running on this message loop are non-nestable. - return PostTask(from_here, task); -} - -bool PluginMessageLoopProxy::PostNonNestableDelayedTask( - const tracked_objects::Location& from_here, - Task* task, - int64 delay_ms) { - // All tasks running on this message loop are non-nestable. - return PostDelayedTask(from_here, task, delay_ms); -} - -bool PluginMessageLoopProxy::PostTask( - const tracked_objects::Location& from_here, - const base::Closure& task) { - return PostDelayedTask(from_here, task, 0); -} - -bool PluginMessageLoopProxy::PostDelayedTask( - const tracked_objects::Location& from_here, - const base::Closure& task, - int64 delay_ms) { - base::AutoLock auto_lock(lock_); - if (!delegate_) { - return false; - } else { - base::Closure* task_on_heap = new base::Closure(task); - return delegate_->RunOnPluginThread( - delay_ms, &PluginMessageLoopProxy::RunClosure, task_on_heap); - } -} - -bool PluginMessageLoopProxy::PostNonNestableTask( - const tracked_objects::Location& from_here, - const base::Closure& task) { - // All tasks running on this message loop are non-nestable. - return PostTask(from_here, task); -} - -bool PluginMessageLoopProxy::PostNonNestableDelayedTask( - const tracked_objects::Location& from_here, - const base::Closure& task, - int64 delay_ms) { - // All tasks running on this message loop are non-nestable. - return PostDelayedTask(from_here, task, delay_ms); -} - -bool PluginMessageLoopProxy::BelongsToCurrentThread() { - base::AutoLock auto_lock(lock_); - if (delegate_) { - return delegate_->IsPluginThread(); - } else { - return false; - } -} - -// static -void PluginMessageLoopProxy::RunTask(void* data) { - Task* task = reinterpret_cast<Task*>(data); - task->Run(); - delete task; -} - -// static -void PluginMessageLoopProxy::RunClosure(void* data) { - base::Closure* task = reinterpret_cast<base::Closure*>(data); - task->Run(); - delete task; -} - -} // namespace remoting diff --git a/remoting/base/plugin_message_loop_proxy.h b/remoting/base/plugin_message_loop_proxy.h deleted file mode 100644 index cfabcd9..0000000 --- a/remoting/base/plugin_message_loop_proxy.h +++ /dev/null @@ -1,79 +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. - -#ifndef REMOTING_BASE_PLUGIN_MESSAGE_LOOP_H_ -#define REMOTING_BASE_PLUGIN_MESSAGE_LOOP_H_ - -#include "base/callback.h" -#include "base/compiler_specific.h" -#include "base/message_loop_proxy.h" - -namespace remoting { - -// MessageLoopProxy for plugin main threads. -class PluginMessageLoopProxy : public base::MessageLoopProxy { - public: - class Delegate { - public: - Delegate() { } - virtual ~Delegate() { } - - virtual bool RunOnPluginThread( - int delay_ms, void(function)(void*), void* data) = 0; - virtual bool IsPluginThread() = 0; - }; - - // Caller keeps ownership of delegate. - PluginMessageLoopProxy(Delegate* delegate); - virtual ~PluginMessageLoopProxy(); - - void Detach(); - - // base::MessageLoopProxy interface. - virtual bool PostTask( - const tracked_objects::Location& from_here, - Task* task) OVERRIDE; - virtual bool PostDelayedTask( - const tracked_objects::Location& from_here, - Task* task, - int64 delay_ms) OVERRIDE; - virtual bool PostNonNestableTask( - const tracked_objects::Location& from_here, - Task* task) OVERRIDE; - virtual bool PostNonNestableDelayedTask( - const tracked_objects::Location& from_here, - Task* task, - int64 delay_ms) OVERRIDE; - - virtual bool PostTask( - const tracked_objects::Location& from_here, - const base::Closure& task) OVERRIDE; - virtual bool PostDelayedTask( - const tracked_objects::Location& from_here, - const base::Closure& task, - int64 delay_ms) OVERRIDE; - virtual bool PostNonNestableTask( - const tracked_objects::Location& from_here, - const base::Closure& task) OVERRIDE; - virtual bool PostNonNestableDelayedTask( - const tracked_objects::Location& from_here, - const base::Closure& task, - int64 delay_ms) OVERRIDE; - - virtual bool BelongsToCurrentThread() OVERRIDE; - - private: - // |lock_| must be acquired when accessing |delegate_|. - base::Lock lock_; - Delegate* delegate_; - - static void RunTask(void* data); - static void RunClosure(void* data); - - DISALLOW_COPY_AND_ASSIGN(PluginMessageLoopProxy); -}; - -} // namespace remoting - -#endif // REMOTING_BASE_PLUGIN_MESSAGE_LOOP_H_ diff --git a/remoting/host/chromoting_host_context.cc b/remoting/host/chromoting_host_context.cc index 6f02943..de99a1f 100644 --- a/remoting/host/chromoting_host_context.cc +++ b/remoting/host/chromoting_host_context.cc @@ -12,12 +12,10 @@ namespace remoting { -ChromotingHostContext::ChromotingHostContext( - base::MessageLoopProxy* ui_message_loop) +ChromotingHostContext::ChromotingHostContext() : main_thread_("ChromotingMainThread"), encode_thread_("ChromotingEncodeThread"), - desktop_thread_("ChromotingDesktopThread"), - ui_message_loop_(ui_message_loop) { + desktop_thread_("ChromotingDesktopThread") { } ChromotingHostContext::~ChromotingHostContext() { @@ -43,10 +41,6 @@ JingleThread* ChromotingHostContext::jingle_thread() { return &jingle_thread_; } -base::MessageLoopProxy* ChromotingHostContext::ui_message_loop() { - return ui_message_loop_; -} - MessageLoop* ChromotingHostContext::main_message_loop() { return main_thread_.message_loop(); } @@ -63,4 +57,31 @@ MessageLoop* ChromotingHostContext::desktop_message_loop() { return desktop_thread_.message_loop(); } +void ChromotingHostContext::SetUITaskPostFunction( + const UIThreadPostTaskFunction& poster) { + ui_poster_ = poster; + ui_main_thread_id_ = base::PlatformThread::CurrentId(); +} + +void ChromotingHostContext::PostTaskToUIThread( + const tracked_objects::Location& from_here, const base::Closure& task) { + ui_poster_.Run(from_here, task); +} + +void ChromotingHostContext::PostDelayedTaskToUIThread( + const tracked_objects::Location& from_here, + const base::Closure& task, + int delay_ms) { + // Post delayed task on the main thread that will post task on UI + // thread. It is safe to use base::Unretained() here because + // ChromotingHostContext owns |main_thread_|. + main_message_loop()->PostDelayedTask(from_here, base::Bind( + &ChromotingHostContext::PostTaskToUIThread, base::Unretained(this), + from_here, task), delay_ms); +} + +bool ChromotingHostContext::IsUIThread() const { + return ui_main_thread_id_ == base::PlatformThread::CurrentId(); +} + } // namespace remoting diff --git a/remoting/host/chromoting_host_context.h b/remoting/host/chromoting_host_context.h index d2ab3e6..38f1cae 100644 --- a/remoting/host/chromoting_host_context.h +++ b/remoting/host/chromoting_host_context.h @@ -25,8 +25,12 @@ namespace remoting { // process. This class is virtual only for testing purposes (see below). class ChromotingHostContext { public: + typedef base::Callback<void( + const tracked_objects::Location& from_here, + const base::Closure& task)> UIThreadPostTaskFunction; + // Create a context. - ChromotingHostContext(base::MessageLoopProxy* ui_message_loop); + ChromotingHostContext(); virtual ~ChromotingHostContext(); // TODO(ajwong): Move the Start/Stop methods out of this class. Then @@ -38,12 +42,21 @@ class ChromotingHostContext { virtual JingleThread* jingle_thread(); - virtual base::MessageLoopProxy* ui_message_loop(); virtual MessageLoop* main_message_loop(); virtual MessageLoop* encode_message_loop(); virtual base::MessageLoopProxy* network_message_loop(); virtual MessageLoop* desktop_message_loop(); + // Must be called from the main GUI thread. + void SetUITaskPostFunction(const UIThreadPostTaskFunction& poster); + + void PostTaskToUIThread(const tracked_objects::Location& from_here, + const base::Closure& task); + void PostDelayedTaskToUIThread(const tracked_objects::Location& from_here, + const base::Closure& task, + int delay_ms); + bool IsUIThread() const; + private: FRIEND_TEST_ALL_PREFIXES(ChromotingHostContextTest, StartAndStop); @@ -60,7 +73,10 @@ class ChromotingHostContext { // This is NOT a Chrome-style UI thread. base::Thread desktop_thread_; - scoped_refptr<base::MessageLoopProxy> ui_message_loop_; + UIThreadPostTaskFunction ui_poster_; + // This IS the main Chrome GUI thread that |ui_poster_| will post to. + base::PlatformThreadId ui_main_thread_id_; + DISALLOW_COPY_AND_ASSIGN(ChromotingHostContext); }; diff --git a/remoting/host/chromoting_host_context_unittest.cc b/remoting/host/chromoting_host_context_unittest.cc index 5d2c5d5..21bcab8 100644 --- a/remoting/host/chromoting_host_context_unittest.cc +++ b/remoting/host/chromoting_host_context_unittest.cc @@ -3,7 +3,6 @@ // found in the LICENSE file. #include "base/message_loop.h" -#include "base/message_loop_proxy.h" #include "remoting/host/chromoting_host_context.h" #include "testing/gtest/include/gtest/gtest.h" @@ -12,10 +11,7 @@ namespace remoting { // A simple test that starts and stop the context. This tests the context // operates properly and all threads and message loops are valid. TEST(ChromotingHostContextTest, StartAndStop) { - MessageLoop message_loop; - ChromotingHostContext context( - base::MessageLoopProxy::CreateForCurrentThread()); - + ChromotingHostContext context; context.Start(); EXPECT_TRUE(context.jingle_thread()); EXPECT_TRUE(context.main_message_loop()); diff --git a/remoting/host/chromoting_host_unittest.cc b/remoting/host/chromoting_host_unittest.cc index 0842832..129d922 100644 --- a/remoting/host/chromoting_host_unittest.cc +++ b/remoting/host/chromoting_host_unittest.cc @@ -78,7 +78,7 @@ class ChromotingHostTest : public testing::Test { ON_CALL(context_, network_message_loop()) .WillByDefault(Return(message_loop_proxy_.get())); ON_CALL(context_, ui_message_loop()) - .WillByDefault(Return(message_loop_proxy_.get())); + .WillByDefault(Return(&message_loop_)); EXPECT_CALL(context_, main_message_loop()) .Times(AnyNumber()); EXPECT_CALL(context_, encode_message_loop()) @@ -88,6 +88,12 @@ class ChromotingHostTest : public testing::Test { EXPECT_CALL(context_, ui_message_loop()) .Times(AnyNumber()); + context_.SetUITaskPostFunction(base::Bind( + static_cast<void(MessageLoop::*)( + const tracked_objects::Location&, + const base::Closure&)>(&MessageLoop::PostTask), + base::Unretained(&message_loop_))); + Capturer* capturer = new CapturerFake(); event_executor_ = new MockEventExecutor(); curtain_ = new MockCurtain(); diff --git a/remoting/host/desktop_environment.cc b/remoting/host/desktop_environment.cc index bdc7ded..8377ac7 100644 --- a/remoting/host/desktop_environment.cc +++ b/remoting/host/desktop_environment.cc @@ -23,30 +23,21 @@ namespace remoting { // thread. This is neccessary so that DesktopEnvironment can be // deleted synchronously even while there are pending tasks on the // message queue. -// -// TODO(sergeyu): Merge this code with remoting::TaskThreadProxy. The -// problem solved by this class is very simular to the one solved by -// ScopedRunnableMethodFactory. The main difference is that this class -// is thread-safe. Change the interface to make it look more like -// ScopedRunnableMethodFactory and rename it to avoid confusion with -// MessageLoopProxy. class UIThreadProxy : public base::RefCountedThreadSafe<UIThreadProxy> { public: - UIThreadProxy(base::MessageLoopProxy* message_loop) - : message_loop_(message_loop) { + UIThreadProxy(ChromotingHostContext* context) + : context_(context) { } - // TODO(sergeyu): Rename this method. void Detach() { - DCHECK(message_loop_->BelongsToCurrentThread()); - message_loop_ = NULL; + DCHECK(context_->IsUIThread()); + context_ = NULL; } void CallOnUIThread(const tracked_objects::Location& from_here, const base::Closure& closure) { - scoped_refptr<base::MessageLoopProxy> message_loop = message_loop_; - if (message_loop) { - message_loop->PostTask(from_here, base::Bind( + if (context_) { + context_->PostTaskToUIThread(from_here, base::Bind( &UIThreadProxy::CallClosure, this, closure)); } } @@ -54,9 +45,8 @@ class UIThreadProxy : public base::RefCountedThreadSafe<UIThreadProxy> { void CallOnUIThreadDelayed(const tracked_objects::Location& from_here, const base::Closure& closure, int delay_ms) { - scoped_refptr<base::MessageLoopProxy> message_loop = message_loop_; - if (message_loop) { - message_loop->PostDelayedTask(from_here, base::Bind( + if (context_) { + context_->PostDelayedTaskToUIThread(from_here, base::Bind( &UIThreadProxy::CallClosure, this, closure), delay_ms); } } @@ -67,11 +57,11 @@ class UIThreadProxy : public base::RefCountedThreadSafe<UIThreadProxy> { virtual ~UIThreadProxy() { } void CallClosure(const base::Closure& closure) { - if (message_loop_) + if (context_) closure.Run(); } - scoped_refptr<base::MessageLoopProxy> message_loop_; + ChromotingHostContext* context_; DISALLOW_COPY_AND_ASSIGN(UIThreadProxy); }; @@ -108,14 +98,14 @@ DesktopEnvironment::DesktopEnvironment(ChromotingHostContext* context, local_input_monitor_(local_input_monitor), is_monitoring_local_inputs_(false), continue_timer_started_(false), - proxy_(new UIThreadProxy(context->ui_message_loop())) { + proxy_(new UIThreadProxy(context)) { } DesktopEnvironment::~DesktopEnvironment() { } void DesktopEnvironment::Shutdown() { - DCHECK(context_->ui_message_loop()->BelongsToCurrentThread()); + DCHECK(context_->IsUIThread()); MonitorLocalInputs(false); ShowDisconnectWindow(false, std::string()); @@ -141,7 +131,7 @@ void DesktopEnvironment::OnPause(bool pause) { } void DesktopEnvironment::ProcessOnConnect(const std::string& username) { - DCHECK(context_->ui_message_loop()->BelongsToCurrentThread()); + DCHECK(context_->IsUIThread()); MonitorLocalInputs(true); ShowDisconnectWindow(true, username); @@ -149,7 +139,7 @@ void DesktopEnvironment::ProcessOnConnect(const std::string& username) { } void DesktopEnvironment::ProcessOnLastDisconnect() { - DCHECK(context_->ui_message_loop()->BelongsToCurrentThread()); + DCHECK(context_->IsUIThread()); MonitorLocalInputs(false); ShowDisconnectWindow(false, std::string()); @@ -162,7 +152,7 @@ void DesktopEnvironment::ProcessOnPause(bool pause) { } void DesktopEnvironment::MonitorLocalInputs(bool enable) { - DCHECK(context_->ui_message_loop()->BelongsToCurrentThread()); + DCHECK(context_->IsUIThread()); if (enable == is_monitoring_local_inputs_) return; @@ -176,7 +166,7 @@ void DesktopEnvironment::MonitorLocalInputs(bool enable) { void DesktopEnvironment::ShowDisconnectWindow(bool show, const std::string& username) { - DCHECK(context_->ui_message_loop()->BelongsToCurrentThread()); + DCHECK(context_->IsUIThread()); if (show) { disconnect_window_->Show(host_, username); @@ -186,7 +176,7 @@ void DesktopEnvironment::ShowDisconnectWindow(bool show, } void DesktopEnvironment::ShowContinueWindow(bool show) { - DCHECK(context_->ui_message_loop()->BelongsToCurrentThread()); + DCHECK(context_->IsUIThread()); if (show) { continue_window_->Show(host_); @@ -196,7 +186,7 @@ void DesktopEnvironment::ShowContinueWindow(bool show) { } void DesktopEnvironment::StartContinueWindowTimer(bool start) { - DCHECK(context_->ui_message_loop()->BelongsToCurrentThread()); + DCHECK(context_->IsUIThread()); if (start && !continue_timer_started_) { continue_timer_target_time_ = base::Time::Now() + @@ -211,7 +201,7 @@ void DesktopEnvironment::StartContinueWindowTimer(bool start) { } void DesktopEnvironment::ContinueWindowTimerFunc() { - DCHECK(context_->ui_message_loop()->BelongsToCurrentThread()); + DCHECK(context_->IsUIThread()); // This function may be called prematurely if timer was stopped and // then started again. In that case we just ignore this call. diff --git a/remoting/host/host_mock_objects.cc b/remoting/host/host_mock_objects.cc index 168e3e8..de0ea97 100644 --- a/remoting/host/host_mock_objects.cc +++ b/remoting/host/host_mock_objects.cc @@ -4,8 +4,6 @@ #include "remoting/host/host_mock_objects.h" -#include "base/message_loop_proxy.h" - namespace remoting { MockCapturer::MockCapturer() {} @@ -48,9 +46,7 @@ LocalInputMonitor* LocalInputMonitor::Create() { return new MockLocalInputMonitor(); } -MockChromotingHostContext::MockChromotingHostContext() - : ChromotingHostContext(base::MessageLoopProxy::CreateForCurrentThread()) { -} +MockChromotingHostContext::MockChromotingHostContext() {} MockChromotingHostContext::~MockChromotingHostContext() {} diff --git a/remoting/host/host_mock_objects.h b/remoting/host/host_mock_objects.h index 67aed7c..5a627ea 100644 --- a/remoting/host/host_mock_objects.h +++ b/remoting/host/host_mock_objects.h @@ -81,10 +81,10 @@ class MockChromotingHostContext : public ChromotingHostContext { MOCK_METHOD0(Start, void()); MOCK_METHOD0(Stop, void()); MOCK_METHOD0(jingle_thread, JingleThread*()); - MOCK_METHOD0(ui_message_loop, base::MessageLoopProxy*()); MOCK_METHOD0(main_message_loop, MessageLoop*()); MOCK_METHOD0(encode_message_loop, MessageLoop*()); MOCK_METHOD0(network_message_loop, base::MessageLoopProxy*()); + MOCK_METHOD0(ui_message_loop, MessageLoop*()); private: DISALLOW_COPY_AND_ASSIGN(MockChromotingHostContext); diff --git a/remoting/host/plugin/host_plugin.cc b/remoting/host/plugin/host_plugin.cc index 0776372..f901a03 100644 --- a/remoting/host/plugin/host_plugin.cc +++ b/remoting/host/plugin/host_plugin.cc @@ -12,7 +12,6 @@ #include "base/basictypes.h" #include "base/logging.h" #include "base/stringize_macros.h" -#include "remoting/base/plugin_message_loop_proxy.h" #include "remoting/host/plugin/host_plugin_utils.h" #include "remoting/host/plugin/host_script_object.h" #include "third_party/npapi/bindings/npapi.h" @@ -59,7 +58,7 @@ base::AtExitManager* g_at_exit_manager = NULL; // NPAPI plugin implementation for remoting host. // Documentation for most of the calls in this class can be found here: // https://developer.mozilla.org/en/Gecko_Plugin_API_Reference/Scripting_plugins -class HostNPPlugin : public remoting::PluginMessageLoopProxy::Delegate { +class HostNPPlugin { public: // |mode| is the display mode of plug-in. Values: // NP_EMBED: (1) Instance was created by an EMBED tag and shares the browser @@ -67,10 +66,7 @@ class HostNPPlugin : public remoting::PluginMessageLoopProxy::Delegate { // NP_FULL: (2) Instance was created by a separate file and is the primary // content in the window. HostNPPlugin(NPP instance, uint16 mode) - : instance_(instance), - scriptable_object_(NULL), - np_thread_id_(base::PlatformThread::CurrentId()) { - } + : instance_(instance), scriptable_object_(NULL) {} ~HostNPPlugin() { if (scriptable_object_) { @@ -150,49 +146,11 @@ class HostNPPlugin : public remoting::PluginMessageLoopProxy::Delegate { return scriptable_object_; } - // PluginMessageLoopProxy::Delegate implementation. - virtual bool RunOnPluginThread( - int delay_ms, void(function)(void*), void* data) OVERRIDE { - if (delay_ms == 0) { - g_npnetscape_funcs->pluginthreadasynccall(instance_, function, data); - } else { - base::AutoLock auto_lock(timers_lock_); - uint32_t timer_id = g_npnetscape_funcs->scheduletimer( - instance_, delay_ms, false, &NPDelayedTaskSpringboard); - DelayedTask task = {function, data}; - timers_[timer_id] = task; - } - return true; - } - - virtual bool IsPluginThread() OVERRIDE { - return np_thread_id_ == base::PlatformThread::CurrentId(); - } - - static void NPDelayedTaskSpringboard(NPP npp, uint32_t timer_id) { - HostNPPlugin* self = reinterpret_cast<HostNPPlugin*>(npp->pdata); - DelayedTask task; - { - base::AutoLock auto_lock(self->timers_lock_); - std::map<uint32_t, DelayedTask>::iterator it = - self->timers_.find(timer_id); - CHECK(it != self->timers_.end()); - task = it->second; - self->timers_.erase(it); - } - task.function(task.data); - } - private: struct ScriptableNPObject : public NPObject { HostNPScriptObject* scriptable_object; }; - struct DelayedTask { - void (*function)(void*); - void* data; - }; - static HostNPScriptObject* ScriptableFromObject(NPObject* obj) { return reinterpret_cast<ScriptableNPObject*>(obj)->scriptable_object; } @@ -202,11 +160,10 @@ class HostNPPlugin : public remoting::PluginMessageLoopProxy::Delegate { ScriptableNPObject* object = reinterpret_cast<ScriptableNPObject*>( g_npnetscape_funcs->memalloc(sizeof(ScriptableNPObject))); - HostNPPlugin* plugin = reinterpret_cast<HostNPPlugin*>(npp->pdata); object->_class = aClass; object->referenceCount = 1; - object->scriptable_object = new HostNPScriptObject(npp, object, plugin); + object->scriptable_object = new HostNPScriptObject(npp, object); if (!object->scriptable_object->Init()) { Deallocate(object); object = NULL; @@ -333,10 +290,6 @@ class HostNPPlugin : public remoting::PluginMessageLoopProxy::Delegate { NPP instance_; NPObject* scriptable_object_; - - base::PlatformThreadId np_thread_id_; - std::map<uint32_t, DelayedTask> timers_; - base::Lock timers_lock_; }; // Utility functions to map NPAPI Entry Points to C++ Objects. diff --git a/remoting/host/plugin/host_script_object.cc b/remoting/host/plugin/host_script_object.cc index 5d26050..8b100c4 100644 --- a/remoting/host/plugin/host_script_object.cc +++ b/remoting/host/plugin/host_script_object.cc @@ -78,17 +78,11 @@ static bool g_logging_to_plugin = false; static HostNPScriptObject* g_logging_scriptable_object = NULL; static logging::LogMessageHandlerFunction g_logging_old_handler = NULL; -HostNPScriptObject::HostNPScriptObject( - NPP plugin, - NPObject* parent, - PluginMessageLoopProxy::Delegate* plugin_thread_delegate) +HostNPScriptObject::HostNPScriptObject(NPP plugin, NPObject* parent) : plugin_(plugin), parent_(parent), state_(kDisconnected), np_thread_id_(base::PlatformThread::CurrentId()), - plugin_message_loop_proxy_( - new PluginMessageLoopProxy(plugin_thread_delegate)), - host_context_(plugin_message_loop_proxy_), failed_login_attempts_(0), disconnected_event_(true, false), nat_traversal_enabled_(false), @@ -105,6 +99,10 @@ HostNPScriptObject::HostNPScriptObject( g_logging_old_handler = logging::GetLogMessageHandler(); logging::SetLogMessageHandler(&LogToUI); g_logging_scriptable_object = this; + + VLOG(2) << "HostNPScriptObject"; + host_context_.SetUITaskPostFunction(base::Bind( + &HostNPScriptObject::PostTaskToNPThread, base::Unretained(this))); } HostNPScriptObject::~HostNPScriptObject() { @@ -118,8 +116,6 @@ HostNPScriptObject::~HostNPScriptObject() { g_logging_old_handler = NULL; g_logging_scriptable_object = NULL; - plugin_message_loop_proxy_->Detach(); - // Stop listening for policy updates. if (nat_policy_.get()) { base::WaitableEvent nat_policy_stopped_(true, false); @@ -132,6 +128,7 @@ HostNPScriptObject::~HostNPScriptObject() { // here because |host_context_| needs to be stopped on the plugin // thread, but the plugin thread may not exist after the instance // is destroyed. + destructing_.Set(); disconnected_event_.Reset(); DisconnectInternal(); disconnected_event_.Wait(); @@ -580,8 +577,11 @@ void HostNPScriptObject::OnReceivedSupportID( } void HostNPScriptObject::OnStateChanged(State state) { - if (!plugin_message_loop_proxy_->BelongsToCurrentThread()) { - plugin_message_loop_proxy_->PostTask( + if (destructing_.IsSet()) + return; + + if (!host_context_.IsUIThread()) { + host_context_.PostTaskToUIThread( FROM_HERE, base::Bind(&HostNPScriptObject::OnStateChanged, base::Unretained(this), state)); return; @@ -615,8 +615,11 @@ bool HostNPScriptObject::LogToUI(int severity, const char* file, int line, } void HostNPScriptObject::LogDebugInfo(const std::string& message) { - if (!plugin_message_loop_proxy_->BelongsToCurrentThread()) { - plugin_message_loop_proxy_->PostTask( + if (destructing_.IsSet()) + return; + + if (!host_context_.IsUIThread()) { + host_context_.PostTaskToUIThread( FROM_HERE, base::Bind(&HostNPScriptObject::LogDebugInfo, base::Unretained(this), message)); return; @@ -701,4 +704,25 @@ bool HostNPScriptObject::InvokeAndIgnoreResult(NPObject* func, return is_good; } +void HostNPScriptObject::PostTaskToNPThread( + const tracked_objects::Location& from_here, const base::Closure& task) { + // The NPAPI functions cannot make use of |from_here|, but this method is + // passed as a callback to ChromotingHostContext, so it needs to have the + // appropriate signature. + + // Copy task to the heap so that we can pass it to NPTaskSpringboard(). + base::Closure* task_in_heap = new base::Closure(task); + + // Can be called from any thread. + g_npnetscape_funcs->pluginthreadasynccall(plugin_, &NPTaskSpringboard, + task_in_heap); +} + +// static +void HostNPScriptObject::NPTaskSpringboard(void* task) { + base::Closure* real_task = reinterpret_cast<base::Closure*>(task); + real_task->Run(); + delete real_task; +} + } // namespace remoting diff --git a/remoting/host/plugin/host_script_object.h b/remoting/host/plugin/host_script_object.h index 04a35b4..2d776ad 100644 --- a/remoting/host/plugin/host_script_object.h +++ b/remoting/host/plugin/host_script_object.h @@ -15,7 +15,6 @@ #include "base/synchronization/waitable_event.h" #include "base/threading/platform_thread.h" #include "base/time.h" -#include "remoting/base/plugin_message_loop_proxy.h" #include "remoting/host/chromoting_host_context.h" #include "remoting/host/host_status_observer.h" #include "remoting/host/plugin/host_plugin_utils.h" @@ -46,8 +45,7 @@ class NatPolicy; // destroyed it sychronously shuts down the host and all threads. class HostNPScriptObject : public HostStatusObserver { public: - HostNPScriptObject(NPP plugin, NPObject* parent, - PluginMessageLoopProxy::Delegate* plugin_thread_delegate); + HostNPScriptObject(NPP plugin, NPObject* parent); virtual ~HostNPScriptObject(); bool Init(); @@ -144,6 +142,13 @@ class HostNPScriptObject : public HostStatusObserver { const NPVariant* args, uint32_t argCount); + // Posts a task on the main NP thread. + void PostTaskToNPThread( + const tracked_objects::Location& from_here, const base::Closure& task); + + // Utility function for PostTaskToNPThread. + static void NPTaskSpringboard(void* task); + // Set an exception for the current call. void SetException(const std::string& exception_string); @@ -157,7 +162,6 @@ class HostNPScriptObject : public HostStatusObserver { ScopedRefNPObject log_debug_info_func_; ScopedRefNPObject on_state_changed_func_; base::PlatformThreadId np_thread_id_; - scoped_refptr<PluginMessageLoopProxy> plugin_message_loop_proxy_; scoped_ptr<RegisterSupportHostRequest> register_request_; scoped_refptr<MutableHostConfig> host_config_; @@ -168,6 +172,7 @@ class HostNPScriptObject : public HostStatusObserver { int failed_login_attempts_; base::WaitableEvent disconnected_event_; + base::CancellationFlag destructing_; scoped_ptr<policy_hack::NatPolicy> nat_policy_; diff --git a/remoting/host/simple_host_process.cc b/remoting/host/simple_host_process.cc index fb99e52..3e6000c 100644 --- a/remoting/host/simple_host_process.cc +++ b/remoting/host/simple_host_process.cc @@ -104,8 +104,13 @@ class SimpleHost { // It needs to be a UI message loop to keep runloops spinning on the Mac. MessageLoop message_loop(MessageLoop::TYPE_UI); - remoting::ChromotingHostContext context( - base::MessageLoopProxy::CreateForCurrentThread()); + remoting::ChromotingHostContext context; + // static_cast needed to resolve overloaded PostTask member-function. + context.SetUITaskPostFunction(base::Bind( + static_cast<void(MessageLoop::*)( + const tracked_objects::Location&, + const base::Closure&)>(&MessageLoop::PostTask), + base::Unretained(&message_loop))); context.Start(); base::Thread file_io_thread("FileIO"); diff --git a/remoting/remoting.gyp b/remoting/remoting.gyp index 6eb1c20..8d00dc7 100644 --- a/remoting/remoting.gyp +++ b/remoting/remoting.gyp @@ -337,8 +337,6 @@ 'base/encoder_vp8.h', 'base/encoder_row_based.cc', 'base/encoder_row_based.h', - 'base/plugin_message_loop_proxy.cc', - 'base/plugin_message_loop_proxy.h', 'base/rate_counter.cc', 'base/rate_counter.h', 'base/running_average.cc', |