diff options
author | sergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-21 03:37:33 +0000 |
---|---|---|
committer | sergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-21 03:37:33 +0000 |
commit | 25f81b94738bab3593129002e20f4f031cc8c94d (patch) | |
tree | 66732ee91308ae883b6e462ed484cf2712028bac /remoting | |
parent | 149b62c5e7f27b9b5f22d69a24a02825adb3238e (diff) | |
download | chromium_src-25f81b94738bab3593129002e20f4f031cc8c94d.zip chromium_src-25f81b94738bab3593129002e20f4f031cc8c94d.tar.gz chromium_src-25f81b94738bab3593129002e20f4f031cc8c94d.tar.bz2 |
Use plugin message loop for main loop in the client plugin.
BUG=None
TEST=None
Review URL: http://codereview.chromium.org/7669037
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@97590 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting')
19 files changed, 272 insertions, 177 deletions
diff --git a/remoting/base/plugin_message_loop_proxy.cc b/remoting/base/plugin_message_loop_proxy.cc index 0f6c668..9022a78 100644 --- a/remoting/base/plugin_message_loop_proxy.cc +++ b/remoting/base/plugin_message_loop_proxy.cc @@ -4,6 +4,8 @@ #include "remoting/base/plugin_message_loop_proxy.h" +#include "base/bind.h" + namespace remoting { PluginMessageLoopProxy::PluginMessageLoopProxy(Delegate* delegate) @@ -15,7 +17,10 @@ PluginMessageLoopProxy::~PluginMessageLoopProxy() { void PluginMessageLoopProxy::Detach() { base::AutoLock auto_lock(lock_); - delegate_ = NULL; + if (delegate_) { + DCHECK(delegate_->IsPluginThread()); + delegate_ = NULL; + } } // MessageLoopProxy interface implementation. @@ -30,12 +35,13 @@ bool PluginMessageLoopProxy::PostDelayedTask( Task* task, int64 delay_ms) { base::AutoLock auto_lock(lock_); - if (!delegate_) { + if (!delegate_) return false; - } else { - return delegate_->RunOnPluginThread( - delay_ms, &PluginMessageLoopProxy::RunTask, task); - } + + base::Closure* springpad_closure = new base::Closure(base::Bind( + &PluginMessageLoopProxy::RunTaskIf, this, task)); + return delegate_->RunOnPluginThread( + delay_ms, &PluginMessageLoopProxy::TaskSpringboard, springpad_closure); } bool PluginMessageLoopProxy::PostNonNestableTask( @@ -64,13 +70,13 @@ bool PluginMessageLoopProxy::PostDelayedTask( const base::Closure& task, int64 delay_ms) { base::AutoLock auto_lock(lock_); - if (!delegate_) { + if (!delegate_) return false; - } else { - base::Closure* task_on_heap = new base::Closure(task); - return delegate_->RunOnPluginThread( - delay_ms, &PluginMessageLoopProxy::RunClosure, task_on_heap); - } + + base::Closure* springpad_closure = new base::Closure(base::Bind( + &PluginMessageLoopProxy::RunClosureIf, this, task)); + return delegate_->RunOnPluginThread( + delay_ms, &PluginMessageLoopProxy::TaskSpringboard, springpad_closure); } bool PluginMessageLoopProxy::PostNonNestableTask( @@ -90,25 +96,32 @@ bool PluginMessageLoopProxy::PostNonNestableDelayedTask( bool PluginMessageLoopProxy::BelongsToCurrentThread() { base::AutoLock auto_lock(lock_); - if (delegate_) { - return delegate_->IsPluginThread(); - } else { + if (!delegate_) return false; - } + + return delegate_->IsPluginThread(); } // static -void PluginMessageLoopProxy::RunTask(void* data) { - Task* task = reinterpret_cast<Task*>(data); +void PluginMessageLoopProxy::TaskSpringboard(void* data) { + base::Closure* task = reinterpret_cast<base::Closure*>(data); task->Run(); delete task; } -// static -void PluginMessageLoopProxy::RunClosure(void* data) { - base::Closure* task = reinterpret_cast<base::Closure*>(data); - task->Run(); +void PluginMessageLoopProxy::RunTaskIf(Task* task) { + // |delegate_| can be changed only from our thread, so it's safe to + // access it without acquiring |lock_|. + if (delegate_) + task->Run(); delete task; } +void PluginMessageLoopProxy::RunClosureIf(const base::Closure& task) { + // |delegate_| can be changed only from our thread, so it's safe to + // access it without acquiring |lock_|. + if (delegate_) + task.Run(); +} + } // namespace remoting diff --git a/remoting/base/plugin_message_loop_proxy.h b/remoting/base/plugin_message_loop_proxy.h index 7b2eef2..04a77b5 100644 --- a/remoting/base/plugin_message_loop_proxy.h +++ b/remoting/base/plugin_message_loop_proxy.h @@ -65,13 +65,15 @@ class PluginMessageLoopProxy : public base::MessageLoopProxy { virtual bool BelongsToCurrentThread() OVERRIDE; private: + static void TaskSpringboard(void* data); + + void RunTaskIf(Task* task); + void RunClosureIf(const base::Closure& task); + // |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); }; diff --git a/remoting/client/chromoting_client.cc b/remoting/client/chromoting_client.cc index b78d4b8..3c033d8 100644 --- a/remoting/client/chromoting_client.cc +++ b/remoting/client/chromoting_client.cc @@ -197,8 +197,6 @@ void ChromotingClient::SetConnectionState(ConnectionState s) { state_ = s; view_->SetConnectionState(s); - - Repaint(); } void ChromotingClient::OnPacketDone(bool last_packet, diff --git a/remoting/client/client_context.cc b/remoting/client/client_context.cc index ca12714..f085778 100644 --- a/remoting/client/client_context.cc +++ b/remoting/client/client_context.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// 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. @@ -6,8 +6,8 @@ namespace remoting { -ClientContext::ClientContext() - : main_thread_("ChromotingClientMainThread"), +ClientContext::ClientContext(base::MessageLoopProxy* main_message_loop_proxy) + : main_message_loop_proxy_(main_message_loop_proxy), decode_thread_("ChromotingClientDecodeThread"), network_thread_("ChromotingClientNetworkThread") { } @@ -17,7 +17,6 @@ ClientContext::~ClientContext() { void ClientContext::Start() { // Start all the threads. - main_thread_.Start(); decode_thread_.Start(); network_thread_.StartWithOptions( base::Thread::Options(MessageLoop::TYPE_IO, 0)); @@ -27,11 +26,10 @@ void ClientContext::Stop() { // Stop all the threads. network_thread_.Stop(); decode_thread_.Stop(); - main_thread_.Stop(); } -MessageLoop* ClientContext::main_message_loop() { - return main_thread_.message_loop(); +base::MessageLoopProxy* ClientContext::main_message_loop() { + return main_message_loop_proxy_; } MessageLoop* ClientContext::decode_message_loop() { diff --git a/remoting/client/client_context.h b/remoting/client/client_context.h index d0d584a..e64303f 100644 --- a/remoting/client/client_context.h +++ b/remoting/client/client_context.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// 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. @@ -16,28 +16,22 @@ namespace remoting { // process. class ClientContext { public: - ClientContext(); + ClientContext(base::MessageLoopProxy* main_message_loop_proxy); virtual ~ClientContext(); void Start(); void Stop(); - MessageLoop* main_message_loop(); + base::MessageLoopProxy* main_message_loop(); MessageLoop* decode_message_loop(); base::MessageLoopProxy* network_message_loop(); private: - // A thread that handles capture rate control and sending data to the - // HostConnection. - base::Thread main_thread_; + scoped_refptr<base::MessageLoopProxy> main_message_loop_proxy_; // A thread that handles all decode operations. base::Thread decode_thread_; - // A thread that handles all network IO. - // - // TODO(sergeyu): Remove |network_thread_| and use main plugin - // message loop for network IO. base::Thread network_thread_; DISALLOW_COPY_AND_ASSIGN(ClientContext); diff --git a/remoting/client/plugin/chromoting_instance.cc b/remoting/client/plugin/chromoting_instance.cc index 6394d56..50be681 100644 --- a/remoting/client/plugin/chromoting_instance.cc +++ b/remoting/client/plugin/chromoting_instance.cc @@ -39,7 +39,6 @@ #include "remoting/client/plugin/pepper_port_allocator_session.h" #include "remoting/client/plugin/pepper_view.h" #include "remoting/client/plugin/pepper_view_proxy.h" -#include "remoting/client/plugin/pepper_util.h" #include "remoting/client/plugin/pepper_xmpp_proxy.h" #include "remoting/client/rectangle_update_decoder.h" #include "remoting/proto/auth.pb.h" @@ -80,6 +79,9 @@ const char* ChromotingInstance::kMimeType = "pepper-application/x-chromoting"; ChromotingInstance::ChromotingInstance(PP_Instance pp_instance) : pp::InstancePrivate(pp_instance), initialized_(false), + plugin_message_loop_( + new PluginMessageLoopProxy(&plugin_thread_delegate_)), + context_(plugin_message_loop_), scale_to_fit_(false), enable_client_nat_traversal_(false), initial_policy_received_(false), @@ -94,7 +96,7 @@ ChromotingInstance::ChromotingInstance(PP_Instance pp_instance) } ChromotingInstance::~ChromotingInstance() { - DCHECK(CurrentlyOnPluginThread()); + 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. @@ -118,6 +120,8 @@ ChromotingInstance::~ChromotingInstance() { if (view_proxy_.get()) { view_proxy_->Detach(); } + + plugin_message_loop_->Detach(); } bool ChromotingInstance::Init(uint32_t argc, @@ -142,7 +146,7 @@ bool ChromotingInstance::Init(uint32_t argc, // Create the chromoting objects that don't depend on the network connection. view_.reset(new PepperView(this, &context_)); - view_proxy_ = new PepperViewProxy(this, view_.get()); + view_proxy_ = new PepperViewProxy(this, view_.get(), plugin_message_loop_); rectangle_decoder_ = new RectangleUpdateDecoder( context_.decode_message_loop(), view_proxy_); @@ -153,7 +157,7 @@ bool ChromotingInstance::Init(uint32_t argc, } void ChromotingInstance::Connect(const ClientConfig& config) { - DCHECK(CurrentlyOnPluginThread()); + DCHECK(plugin_message_loop_->BelongsToCurrentThread()); // This can only happen at initialization if the Javascript connect call // occurs before the enterprise policy is read. We are guaranteed that the @@ -176,7 +180,8 @@ void ChromotingInstance::Connect(const ClientConfig& config) { IpcPacketSocketFactory* socket_factory = NULL; HostResolverFactory* host_resolver_factory = NULL; PortAllocatorSessionFactory* session_factory = - CreatePepperPortAllocatorSessionFactory(this); + CreatePepperPortAllocatorSessionFactory( + this, plugin_message_loop_, context_.network_message_loop()); // If we don't have socket dispatcher for IPC (e.g. P2P API is // disabled), then JingleSessionManager will try to use physical sockets. @@ -204,6 +209,7 @@ void ChromotingInstance::Connect(const ClientConfig& config) { ChromotingScriptableObject* scriptable_object = GetScriptableObject(); scoped_refptr<PepperXmppProxy> xmpp_proxy = new PepperXmppProxy(scriptable_object->AsWeakPtr(), + plugin_message_loop_, context_.network_message_loop()); scriptable_object->AttachXmppProxy(xmpp_proxy); @@ -216,7 +222,7 @@ void ChromotingInstance::Connect(const ClientConfig& config) { } void ChromotingInstance::Disconnect() { - DCHECK(CurrentlyOnPluginThread()); + DCHECK(plugin_message_loop_->BelongsToCurrentThread()); LOG(INFO) << "Disconnecting from host."; if (client_.get()) { @@ -236,7 +242,7 @@ void ChromotingInstance::Disconnect() { void ChromotingInstance::DidChangeView(const pp::Rect& position, const pp::Rect& clip) { - DCHECK(CurrentlyOnPluginThread()); + DCHECK(plugin_message_loop_->BelongsToCurrentThread()); bool size_changed = view_->SetPluginSize(gfx::Size(position.width(), position.height())); @@ -258,7 +264,7 @@ void ChromotingInstance::DidChangeView(const pp::Rect& position, } bool ChromotingInstance::HandleInputEvent(const pp::InputEvent& event) { - DCHECK(CurrentlyOnPluginThread()); + DCHECK(plugin_message_loop_->BelongsToCurrentThread()); if (!input_handler_.get()) { return false; } @@ -349,7 +355,7 @@ void ChromotingInstance::SubmitLoginInfo(const std::string& username, } void ChromotingInstance::SetScaleToFit(bool scale_to_fit) { - DCHECK(CurrentlyOnPluginThread()); + DCHECK(plugin_message_loop_->BelongsToCurrentThread()); if (scale_to_fit == scale_to_fit_) return; @@ -525,7 +531,7 @@ bool ChromotingInstance::IsNatTraversalAllowed( } void ChromotingInstance::HandlePolicyUpdate(const std::string policy_json) { - DCHECK(CurrentlyOnPluginThread()); + DCHECK(plugin_message_loop_->BelongsToCurrentThread()); bool traversal_policy = IsNatTraversalAllowed(policy_json); // If the policy changes from traversal allowed, to traversal denied, we @@ -542,9 +548,8 @@ void ChromotingInstance::HandlePolicyUpdate(const std::string policy_json) { initial_policy_received_ = true; enable_client_nat_traversal_ = traversal_policy; - if (delayed_connect_.get()) { - RunTaskOnPluginThread(delayed_connect_.release()); - } + if (delayed_connect_.get()) + plugin_message_loop_->PostTask(FROM_HERE, delayed_connect_.release()); } } // namespace remoting diff --git a/remoting/client/plugin/chromoting_instance.h b/remoting/client/plugin/chromoting_instance.h index 36295d5..e1b62cc 100644 --- a/remoting/client/plugin/chromoting_instance.h +++ b/remoting/client/plugin/chromoting_instance.h @@ -21,6 +21,7 @@ #include "ppapi/cpp/private/instance_private.h" #include "remoting/client/client_context.h" #include "remoting/client/plugin/chromoting_scriptable_object.h" +#include "remoting/client/plugin/pepper_plugin_thread_delegate.h" #include "remoting/protocol/connection_to_host.h" namespace base { @@ -129,6 +130,8 @@ class ChromotingInstance : public pp::InstancePrivate { bool initialized_; + PepperPluginThreadDelegate plugin_thread_delegate_; + scoped_refptr<PluginMessageLoopProxy> plugin_message_loop_; ClientContext context_; scoped_ptr<protocol::ConnectionToHost> host_connection_; scoped_ptr<PepperView> view_; diff --git a/remoting/client/plugin/pepper_plugin_thread_delegate.cc b/remoting/client/plugin/pepper_plugin_thread_delegate.cc new file mode 100644 index 0000000..b91fef3 --- /dev/null +++ b/remoting/client/plugin/pepper_plugin_thread_delegate.cc @@ -0,0 +1,35 @@ +// 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/client/plugin/pepper_plugin_thread_delegate.h" + +#include "ppapi/cpp/completion_callback.h" +#include "ppapi/cpp/module.h" + +namespace remoting { + +PepperPluginThreadDelegate::PepperPluginThreadDelegate() + : core_(pp::Module::Get()->core()) { +} + +PepperPluginThreadDelegate::~PepperPluginThreadDelegate() { } + +bool PepperPluginThreadDelegate::RunOnPluginThread( + int delay_ms, void(CDECL function)(void*), void* data) { + // It is safe to cast |function| to PP_CompletionCallback_Func, + // which is defined as void(*)(void*, int). The callee will just + // ignore the last argument. The only case when it may be unsafe is + // with VS when default calling convention is set to __stdcall, but + // this code will not typecheck in that case. + core_->CallOnMainThread( + delay_ms, pp::CompletionCallback( + reinterpret_cast<PP_CompletionCallback_Func>(function), data), 0); + return true; +} + +bool PepperPluginThreadDelegate::IsPluginThread() { + return core_->IsMainThread(); +} + +} // namespace remoting diff --git a/remoting/client/plugin/pepper_plugin_thread_delegate.h b/remoting/client/plugin/pepper_plugin_thread_delegate.h new file mode 100644 index 0000000..38f1359 --- /dev/null +++ b/remoting/client/plugin/pepper_plugin_thread_delegate.h @@ -0,0 +1,39 @@ +// 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_CLIENT_PLUGIN_PEPPER_PLUGIN_THREAD_DELEGATE_H_ +#define REMOTING_CLIENT_PLUGIN_PEPPER_PLUGIN_THREAD_DELEGATE_H_ + +#include "remoting/base/plugin_message_loop_proxy.h" + +// Macro useful for writing cross-platform function pointers. +#if defined(OS_WIN) && !defined(CDECL) +#define CDECL __cdecl +#else +#define CDECL +#endif + +namespace pp { +class Core; +} // namespace pp + +namespace remoting { + +class PepperPluginThreadDelegate : public PluginMessageLoopProxy::Delegate { + public: + PepperPluginThreadDelegate(); + virtual ~PepperPluginThreadDelegate(); + + virtual bool RunOnPluginThread( + int delay_ms, void(CDECL function)(void*), void* data) OVERRIDE; + + virtual bool IsPluginThread() OVERRIDE; + + private: + pp::Core* core_; +}; + +} // namespace remoting + +#endif // REMOTING_CLIENT_PLUGIN_PEPPER_PLUGIN_THREAD_DELEGATE_H_ diff --git a/remoting/client/plugin/pepper_port_allocator_session.cc b/remoting/client/plugin/pepper_port_allocator_session.cc index ec7544e9..8127b76 100644 --- a/remoting/client/plugin/pepper_port_allocator_session.cc +++ b/remoting/client/plugin/pepper_port_allocator_session.cc @@ -6,8 +6,10 @@ #include <map> +#include "base/bind.h" #include "base/callback.h" #include "base/logging.h" +#include "base/message_loop_proxy.h" #include "base/string_util.h" #include "base/stringprintf.h" #include "base/synchronization/lock.h" @@ -19,7 +21,6 @@ #include "remoting/jingle_glue/http_port_allocator.h" #include "remoting/client/plugin/chromoting_instance.h" #include "remoting/client/plugin/pepper_entrypoints.h" -#include "remoting/client/plugin/pepper_util.h" namespace { @@ -33,9 +34,11 @@ static const std::string kCreateSessionURL = "/create_session"; class SessionFactory : public remoting::PortAllocatorSessionFactory { public: SessionFactory(remoting::ChromotingInstance* instance, - MessageLoop* message_loop) + base::MessageLoopProxy* pepper_message_loop, + base::MessageLoopProxy* network_message_loop) : instance_(instance), - jingle_message_loop_(message_loop) { + pepper_message_loop_(pepper_message_loop), + network_message_loop_(network_message_loop) { } virtual cricket::PortAllocatorSession* CreateSession( @@ -47,15 +50,15 @@ class SessionFactory : public remoting::PortAllocatorSessionFactory { const std::string& relay, const std::string& agent) { return new remoting::PepperPortAllocatorSession( - instance_, jingle_message_loop_, allocator, name, session_type, - stun_hosts, relay_hosts, relay, agent); + instance_, pepper_message_loop_, network_message_loop_, allocator, + name, session_type, stun_hosts, relay_hosts, relay, agent); } private: remoting::ChromotingInstance* instance_; - // Message loop that jingle runs on. - MessageLoop* jingle_message_loop_; + scoped_refptr<base::MessageLoopProxy> pepper_message_loop_; + scoped_refptr<base::MessageLoopProxy> network_message_loop_; DISALLOW_COPY_AND_ASSIGN(SessionFactory); }; @@ -176,12 +179,13 @@ static void DeletePepperURLFetcher(PepperURLFetcher* fetcher) { } // A helper class to do HTTP request on the pepper thread and then delegate the -// result to PepperPortAllocatorSession on jingle thread safely. +// result to PepperPortAllocatorSession on network thread safely. class PepperCreateSessionTask : public base::RefCountedThreadSafe<PepperCreateSessionTask> { public: PepperCreateSessionTask( - MessageLoop* jingle_message_loop, + base::MessageLoopProxy* plugin_message_loop, + base::MessageLoopProxy* network_message_loop, PepperPortAllocatorSession* allocator_session, ChromotingInstance* instance, const std::string& host, @@ -189,7 +193,8 @@ class PepperCreateSessionTask const std::string& relay_token, const std::string& session_type, const std::string& name) - : jingle_message_loop_(jingle_message_loop), + : plugin_message_loop_(plugin_message_loop), + network_message_loop_(network_message_loop), allocator_session_(allocator_session), instance_(instance), host_(host), @@ -201,9 +206,9 @@ class PepperCreateSessionTask // Start doing the request. The request will start on the pepper thread. void Start() { - if (!CurrentlyOnPluginThread()) { - RunTaskOnPluginThread( - NewRunnableMethod(this, &PepperCreateSessionTask::Start)); + if (!plugin_message_loop_->BelongsToCurrentThread()) { + plugin_message_loop_->PostTask( + FROM_HERE, base::Bind(&PepperCreateSessionTask::Start, this)); return; } @@ -233,15 +238,15 @@ class PepperCreateSessionTask // Set the pointers to zero. { base::AutoLock auto_lock(lock_); - jingle_message_loop_ = NULL; + network_message_loop_ = NULL; allocator_session_ = NULL; instance_ = NULL; } // IMPORTANT! // Destroy PepperURLFetcher only on pepper thread. - RunTaskOnPluginThread( - NewRunnableFunction(&DeletePepperURLFetcher, url_fetcher_.release())); + plugin_message_loop_->PostTask( + FROM_HERE, base::Bind(&DeletePepperURLFetcher, url_fetcher_.release())); } private: @@ -249,18 +254,17 @@ class PepperCreateSessionTask const std::string& response) { // IMPORTANT! // This method is called on the pepper thread and we want the response to - // be delegated to the jingle thread. However jignle thread might have + // be delegated to the network thread. However jignle thread might have // been destroyed and |allocator_session_| might be dangling too. So we - // put a lock here to access |jingle_message_loop_| and then do the - // remaining work on the jingle thread. + // put a lock here to access |network_message_loop_| and then do the + // remaining work on the network thread. base::AutoLock auto_lock(lock_); - if (!jingle_message_loop_) + if (!network_message_loop_) return; - jingle_message_loop_->PostTask( - FROM_HERE, - NewRunnableMethod(this, &PepperCreateSessionTask::DelegateRequestDone, - success, status_code, response)); + network_message_loop_->PostTask( + FROM_HERE, base::Bind(&PepperCreateSessionTask::DelegateRequestDone, + this, success, status_code, response)); } void DelegateRequestDone(bool success, int status_code, @@ -270,10 +274,11 @@ class PepperCreateSessionTask allocator_session_->OnRequestDone(success, status_code, response); } - // Protects |jingle_message_loop_|. + // Protects |network_message_loop_| and |allocator_session_|. base::Lock lock_; - MessageLoop* jingle_message_loop_; + scoped_refptr<base::MessageLoopProxy> plugin_message_loop_; + scoped_refptr<base::MessageLoopProxy> network_message_loop_; PepperPortAllocatorSession* allocator_session_; ChromotingInstance* instance_; std::string host_; @@ -290,7 +295,8 @@ class PepperCreateSessionTask PepperPortAllocatorSession::PepperPortAllocatorSession( ChromotingInstance* instance, - MessageLoop* message_loop, + base::MessageLoopProxy* plugin_message_loop, + base::MessageLoopProxy* network_message_loop, cricket::BasicPortAllocator* allocator, const std::string &name, const std::string& session_type, @@ -299,7 +305,8 @@ PepperPortAllocatorSession::PepperPortAllocatorSession( const std::string& relay_token, const std::string& user_agent) : BasicPortAllocatorSession(allocator, name, session_type), - instance_(instance), jingle_message_loop_(message_loop), + instance_(instance), plugin_message_loop_(plugin_message_loop), + network_message_loop_(network_message_loop), relay_hosts_(relay_hosts), stun_hosts_(stun_hosts), relay_token_(relay_token), agent_(user_agent), attempts_(0) { } @@ -357,15 +364,15 @@ void PepperPortAllocatorSession::SendSessionRequest(const std::string& host, // Construct a new one and start it. OnRequestDone() will be called when // task has completed. create_session_task_ = new PepperCreateSessionTask( - jingle_message_loop_, this, instance_, host, port, relay_token_, - session_type(), name()); + plugin_message_loop_, network_message_loop_, this, instance_, + host, port, relay_token_, session_type(), name()); create_session_task_->Start(); } void PepperPortAllocatorSession::OnRequestDone(bool success, int status_code, const std::string& response) { - DCHECK_EQ(jingle_message_loop_, MessageLoop::current()); + DCHECK(network_message_loop_->BelongsToCurrentThread()); if (!success || status_code != 200) { LOG(WARNING) << "PepperPortAllocatorSession: failed."; @@ -413,8 +420,10 @@ void PepperPortAllocatorSession::ReceiveSessionResponse( } PortAllocatorSessionFactory* CreatePepperPortAllocatorSessionFactory( - ChromotingInstance* instance) { - return new SessionFactory(instance, MessageLoop::current()); + ChromotingInstance* instance, base::MessageLoopProxy* plugin_message_loop, + base::MessageLoopProxy* network_message_loop) { + return new SessionFactory(instance, plugin_message_loop, + network_message_loop); } } // namespace remoting diff --git a/remoting/client/plugin/pepper_port_allocator_session.h b/remoting/client/plugin/pepper_port_allocator_session.h index fa30ebe..fb1d9ab 100644 --- a/remoting/client/plugin/pepper_port_allocator_session.h +++ b/remoting/client/plugin/pepper_port_allocator_session.h @@ -5,10 +5,14 @@ #ifndef REMOTING_CLIENT_PLUGIN_PEPPER_PORT_ALLOCATOR_SESSION_H_ #define REMOTING_CLIENT_PLUGIN_PEPPER_PORT_ALLOCATOR_SESSION_H_ -#include "base/message_loop.h" +#include "base/memory/ref_counted.h" #include "ppapi/cpp/completion_callback.h" #include "third_party/libjingle/source/talk/p2p/client/basicportallocator.h" +namespace base { +class MessageLoopProxy; +} // namespace base + namespace remoting { class ChromotingInstance; @@ -20,7 +24,8 @@ class PepperPortAllocatorSession : public cricket::BasicPortAllocatorSession { public: PepperPortAllocatorSession( ChromotingInstance* instance, - MessageLoop* message_loop, + base::MessageLoopProxy* plugin_message_loop, + base::MessageLoopProxy* network_message_loop, cricket::BasicPortAllocator* allocator, const std::string& name, const std::string& session_type, @@ -47,7 +52,8 @@ class PepperPortAllocatorSession : public cricket::BasicPortAllocatorSession { void TryCreateRelaySession(); ChromotingInstance* const instance_; - MessageLoop* const jingle_message_loop_; + scoped_refptr<base::MessageLoopProxy> plugin_message_loop_; + scoped_refptr<base::MessageLoopProxy> network_message_loop_; std::vector<std::string> relay_hosts_; std::vector<talk_base::SocketAddress> stun_hosts_; @@ -61,7 +67,9 @@ class PepperPortAllocatorSession : public cricket::BasicPortAllocatorSession { }; PortAllocatorSessionFactory* CreatePepperPortAllocatorSessionFactory( - ChromotingInstance* instance); + ChromotingInstance* instance, base::MessageLoopProxy* plugin_message_loop, + base::MessageLoopProxy* network_message_loop); + } // namespace remoting diff --git a/remoting/client/plugin/pepper_util.cc b/remoting/client/plugin/pepper_util.cc index 4a01c2d..2a726d2 100644 --- a/remoting/client/plugin/pepper_util.cc +++ b/remoting/client/plugin/pepper_util.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// 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. @@ -20,16 +20,4 @@ pp::CompletionCallback TaskToCompletionCallback(Task* task) { return pp::CompletionCallback(&CompletionCallbackTaskAdapter, task); } -void RunTaskOnPluginThread(Task* task) { - pp::Module::Get()->core()->CallOnMainThread( - 0 /* run immediately */, - TaskToCompletionCallback(task), - 0 /* unused value */ - ); -} - -bool CurrentlyOnPluginThread() { - return pp::Module::Get()->core()->IsMainThread(); -} - } // namespace remoting diff --git a/remoting/client/plugin/pepper_util.h b/remoting/client/plugin/pepper_util.h index 6014824..9de64bc 100644 --- a/remoting/client/plugin/pepper_util.h +++ b/remoting/client/plugin/pepper_util.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// 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. @@ -23,13 +23,6 @@ void CompletionCallbackTaskAdapter(void* user_data, int32_t not_used); // APIs that require a pp::CompletionCallback. Takes ownership of |task|. pp::CompletionCallback TaskToCompletionCallback(Task* task); -// Posts the current task to the plugin's main thread. Takes ownership of -// |task|. -void RunTaskOnPluginThread(Task* task); - -// Returns true if the current thread is the plugin main thread. -bool CurrentlyOnPluginThread(); - } // namespace remoting #endif // REMOTING_CLIENT_PLUGIN_PLUGIN_UTIL_H_ diff --git a/remoting/client/plugin/pepper_view.cc b/remoting/client/plugin/pepper_view.cc index f85ca71..b227402 100644 --- a/remoting/client/plugin/pepper_view.cc +++ b/remoting/client/plugin/pepper_view.cc @@ -37,13 +37,13 @@ bool PepperView::Initialize() { } void PepperView::TearDown() { - DCHECK(CurrentlyOnPluginThread()); + DCHECK(context_->main_message_loop()->BelongsToCurrentThread()); task_factory_.RevokeAll(); } void PepperView::Paint() { - DCHECK(CurrentlyOnPluginThread()); + DCHECK(context_->main_message_loop()->BelongsToCurrentThread()); TraceContext::tracer()->PrintString("Start Paint."); @@ -79,7 +79,7 @@ void PepperView::Paint() { } void PepperView::SetHostSize(const gfx::Size& host_size) { - DCHECK(CurrentlyOnPluginThread()); + DCHECK(context_->main_message_loop()->BelongsToCurrentThread()); if (host_size_ == host_size) return; @@ -92,7 +92,7 @@ void PepperView::SetHostSize(const gfx::Size& host_size) { } void PepperView::PaintFrame(media::VideoFrame* frame, UpdatedRects* rects) { - DCHECK(CurrentlyOnPluginThread()); + DCHECK(context_->main_message_loop()->BelongsToCurrentThread()); TraceContext::tracer()->PrintString("Start Paint Frame."); @@ -194,20 +194,22 @@ void PepperView::FlushGraphics(base::Time paint_start) { } void PepperView::SetSolidFill(uint32 color) { - DCHECK(CurrentlyOnPluginThread()); + DCHECK(context_->main_message_loop()->BelongsToCurrentThread()); is_static_fill_ = true; static_fill_color_ = color; + + Paint(); } void PepperView::UnsetSolidFill() { - DCHECK(CurrentlyOnPluginThread()); + DCHECK(context_->main_message_loop()->BelongsToCurrentThread()); is_static_fill_ = false; } void PepperView::SetConnectionState(ConnectionState state) { - DCHECK(CurrentlyOnPluginThread()); + DCHECK(context_->main_message_loop()->BelongsToCurrentThread()); // TODO(hclam): Re-consider the way we communicate with Javascript. ChromotingScriptableObject* scriptable_obj = instance_->GetScriptableObject(); @@ -235,7 +237,7 @@ void PepperView::SetConnectionState(ConnectionState state) { } void PepperView::UpdateLoginStatus(bool success, const std::string& info) { - DCHECK(CurrentlyOnPluginThread()); + DCHECK(context_->main_message_loop()->BelongsToCurrentThread()); // TODO(hclam): Re-consider the way we communicate with Javascript. ChromotingScriptableObject* scriptable_obj = instance_->GetScriptableObject(); @@ -298,7 +300,7 @@ void PepperView::AllocateFrame(media::VideoFrame::Format format, base::TimeDelta duration, scoped_refptr<media::VideoFrame>* frame_out, Task* done) { - DCHECK(CurrentlyOnPluginThread()); + DCHECK(context_->main_message_loop()->BelongsToCurrentThread()); *frame_out = media::VideoFrame::CreateFrame(media::VideoFrame::RGB32, width, height, @@ -310,7 +312,7 @@ void PepperView::AllocateFrame(media::VideoFrame::Format format, } void PepperView::ReleaseFrame(media::VideoFrame* frame) { - DCHECK(CurrentlyOnPluginThread()); + DCHECK(context_->main_message_loop()->BelongsToCurrentThread()); if (frame) { LOG(WARNING) << "Frame released."; @@ -321,7 +323,7 @@ void PepperView::ReleaseFrame(media::VideoFrame* frame) { void PepperView::OnPartialFrameOutput(media::VideoFrame* frame, UpdatedRects* rects, Task* done) { - DCHECK(CurrentlyOnPluginThread()); + DCHECK(context_->main_message_loop()->BelongsToCurrentThread()); TraceContext::tracer()->PrintString("Calling PaintFrame"); // TODO(ajwong): Clean up this API to be async so we don't need to use a @@ -332,7 +334,7 @@ void PepperView::OnPartialFrameOutput(media::VideoFrame* frame, } void PepperView::OnPaintDone(base::Time paint_start) { - DCHECK(CurrentlyOnPluginThread()); + DCHECK(context_->main_message_loop()->BelongsToCurrentThread()); TraceContext::tracer()->PrintString("Paint flushed"); instance_->GetStats()->video_paint_ms()->Record( (base::Time::Now() - paint_start).InMilliseconds()); diff --git a/remoting/client/plugin/pepper_view_proxy.cc b/remoting/client/plugin/pepper_view_proxy.cc index e1f0672..6599f3c 100644 --- a/remoting/client/plugin/pepper_view_proxy.cc +++ b/remoting/client/plugin/pepper_view_proxy.cc @@ -8,13 +8,14 @@ #include "remoting/base/tracer.h" #include "remoting/client/client_context.h" #include "remoting/client/plugin/chromoting_instance.h" -#include "remoting/client/plugin/pepper_util.h" namespace remoting { -PepperViewProxy::PepperViewProxy(ChromotingInstance* instance, PepperView* view) +PepperViewProxy::PepperViewProxy(ChromotingInstance* instance, PepperView* view, + base::MessageLoopProxy* plugin_message_loop) : instance_(instance), - view_(view) { + view_(view), + plugin_message_loop_(plugin_message_loop) { } PepperViewProxy::~PepperViewProxy() { @@ -28,8 +29,9 @@ bool PepperViewProxy::Initialize() { } void PepperViewProxy::TearDown() { - if (instance_ && !CurrentlyOnPluginThread()) { - RunTaskOnPluginThread(NewTracedMethod(this, &PepperViewProxy::TearDown)); + if (instance_ && !plugin_message_loop_->BelongsToCurrentThread()) { + plugin_message_loop_->PostTask( + FROM_HERE, NewTracedMethod(this, &PepperViewProxy::TearDown)); return; } @@ -38,8 +40,9 @@ void PepperViewProxy::TearDown() { } void PepperViewProxy::Paint() { - if (instance_ && !CurrentlyOnPluginThread()) { - RunTaskOnPluginThread(NewTracedMethod(this, &PepperViewProxy::Paint)); + if (instance_ && !plugin_message_loop_->BelongsToCurrentThread()) { + plugin_message_loop_->PostTask( + FROM_HERE, NewTracedMethod(this, &PepperViewProxy::Paint)); return; } @@ -48,9 +51,9 @@ void PepperViewProxy::Paint() { } void PepperViewProxy::SetSolidFill(uint32 color) { - if (instance_ && !CurrentlyOnPluginThread()) { - RunTaskOnPluginThread( - NewTracedMethod(this, &PepperViewProxy::SetSolidFill, color)); + if (instance_ && !plugin_message_loop_->BelongsToCurrentThread()) { + plugin_message_loop_->PostTask(FROM_HERE, NewTracedMethod( + this, &PepperViewProxy::SetSolidFill, color)); return; } @@ -59,9 +62,9 @@ void PepperViewProxy::SetSolidFill(uint32 color) { } void PepperViewProxy::UnsetSolidFill() { - if (instance_ && !CurrentlyOnPluginThread()) { - RunTaskOnPluginThread( - NewTracedMethod(this, &PepperViewProxy::UnsetSolidFill)); + if (instance_ && !plugin_message_loop_->BelongsToCurrentThread()) { + plugin_message_loop_->PostTask( + FROM_HERE, NewTracedMethod(this, &PepperViewProxy::UnsetSolidFill)); return; } @@ -70,9 +73,9 @@ void PepperViewProxy::UnsetSolidFill() { } void PepperViewProxy::SetConnectionState(ConnectionState state) { - if (instance_ && !CurrentlyOnPluginThread()) { - RunTaskOnPluginThread( - NewRunnableMethod(this, &PepperViewProxy::SetConnectionState, state)); + if (instance_ && !plugin_message_loop_->BelongsToCurrentThread()) { + plugin_message_loop_->PostTask(FROM_HERE, NewRunnableMethod( + this, &PepperViewProxy::SetConnectionState, state)); return; } @@ -81,10 +84,9 @@ void PepperViewProxy::SetConnectionState(ConnectionState state) { } void PepperViewProxy::UpdateLoginStatus(bool success, const std::string& info) { - if (instance_ && !CurrentlyOnPluginThread()) { - RunTaskOnPluginThread(NewTracedMethod(this, - &PepperViewProxy::UpdateLoginStatus, - success, info)); + if (instance_ && !plugin_message_loop_->BelongsToCurrentThread()) { + plugin_message_loop_->PostTask(FROM_HERE, NewTracedMethod( + this, &PepperViewProxy::UpdateLoginStatus, success, info)); return; } @@ -95,7 +97,7 @@ void PepperViewProxy::UpdateLoginStatus(bool success, const std::string& info) { double PepperViewProxy::GetHorizontalScaleRatio() const { // This method returns a value, so must run synchronously, so must be // called only on the pepper thread. - DCHECK(CurrentlyOnPluginThread()); + DCHECK(plugin_message_loop_->BelongsToCurrentThread()); if (view_) return view_->GetHorizontalScaleRatio(); @@ -105,7 +107,7 @@ double PepperViewProxy::GetHorizontalScaleRatio() const { double PepperViewProxy::GetVerticalScaleRatio() const { // This method returns a value, so must run synchronously, so must be // called only on the pepper thread. - DCHECK(CurrentlyOnPluginThread()); + DCHECK(plugin_message_loop_->BelongsToCurrentThread()); if (view_) return view_->GetVerticalScaleRatio(); @@ -120,10 +122,10 @@ void PepperViewProxy::AllocateFrame( base::TimeDelta duration, scoped_refptr<media::VideoFrame>* frame_out, Task* done) { - if (instance_ && !CurrentlyOnPluginThread()) { - RunTaskOnPluginThread( - NewTracedMethod(this, &PepperViewProxy::AllocateFrame, format, width, - height, timestamp, duration, frame_out, done)); + if (instance_ && !plugin_message_loop_->BelongsToCurrentThread()) { + plugin_message_loop_->PostTask(FROM_HERE, NewTracedMethod( + this, &PepperViewProxy::AllocateFrame, format, width, + height, timestamp, duration, frame_out, done)); return; } @@ -134,10 +136,9 @@ void PepperViewProxy::AllocateFrame( } void PepperViewProxy::ReleaseFrame(media::VideoFrame* frame) { - if (instance_ && !CurrentlyOnPluginThread()) { - RunTaskOnPluginThread( - NewTracedMethod(this, &PepperViewProxy::ReleaseFrame, - make_scoped_refptr(frame))); + if (instance_ && !plugin_message_loop_->BelongsToCurrentThread()) { + plugin_message_loop_->PostTask(FROM_HERE, NewTracedMethod( + this, &PepperViewProxy::ReleaseFrame, make_scoped_refptr(frame))); return; } @@ -148,10 +149,10 @@ void PepperViewProxy::ReleaseFrame(media::VideoFrame* frame) { void PepperViewProxy::OnPartialFrameOutput(media::VideoFrame* frame, UpdatedRects* rects, Task* done) { - if (instance_ && !CurrentlyOnPluginThread()) { - RunTaskOnPluginThread( - NewTracedMethod(this, &PepperViewProxy::OnPartialFrameOutput, - make_scoped_refptr(frame), rects, done)); + if (instance_ && !plugin_message_loop_->BelongsToCurrentThread()) { + plugin_message_loop_->PostTask(FROM_HERE, NewTracedMethod( + this, &PepperViewProxy::OnPartialFrameOutput, + make_scoped_refptr(frame), rects, done)); return; } @@ -160,7 +161,7 @@ void PepperViewProxy::OnPartialFrameOutput(media::VideoFrame* frame, } void PepperViewProxy::Detach() { - DCHECK(CurrentlyOnPluginThread()); + DCHECK(plugin_message_loop_->BelongsToCurrentThread()); instance_ = NULL; view_ = NULL; } diff --git a/remoting/client/plugin/pepper_view_proxy.h b/remoting/client/plugin/pepper_view_proxy.h index b9053b3..4f65ce6 100644 --- a/remoting/client/plugin/pepper_view_proxy.h +++ b/remoting/client/plugin/pepper_view_proxy.h @@ -19,6 +19,10 @@ #include "base/memory/ref_counted.h" #include "remoting/client/plugin/pepper_view.h" +namespace base { +class MessageLoopProxy; +} // namespace base + namespace remoting { class ChromotingInstance; @@ -28,7 +32,8 @@ class PepperViewProxy : public base::RefCountedThreadSafe<PepperViewProxy>, public ChromotingView, public FrameConsumer { public: - PepperViewProxy(ChromotingInstance* instance, PepperView* view); + PepperViewProxy(ChromotingInstance* instance, PepperView* view, + base::MessageLoopProxy* plugin_message_loop); virtual ~PepperViewProxy(); // ChromotingView implementation. @@ -76,6 +81,8 @@ class PepperViewProxy : public base::RefCountedThreadSafe<PepperViewProxy>, // necessary. PepperView* view_; + scoped_refptr<base::MessageLoopProxy> plugin_message_loop_; + DISALLOW_COPY_AND_ASSIGN(PepperViewProxy); }; diff --git a/remoting/client/plugin/pepper_xmpp_proxy.cc b/remoting/client/plugin/pepper_xmpp_proxy.cc index fb96bd1..9400c0b7a 100644 --- a/remoting/client/plugin/pepper_xmpp_proxy.cc +++ b/remoting/client/plugin/pepper_xmpp_proxy.cc @@ -4,19 +4,20 @@ #include "remoting/client/plugin/pepper_xmpp_proxy.h" -#include "base/message_loop.h" +#include "base/bind.h" #include "base/message_loop_proxy.h" #include "remoting/client/plugin/chromoting_scriptable_object.h" -#include "remoting/client/plugin/pepper_util.h" namespace remoting { PepperXmppProxy::PepperXmppProxy( base::WeakPtr<ChromotingScriptableObject> scriptable_object, + base::MessageLoopProxy* plugin_message_loop, base::MessageLoopProxy* callback_message_loop) : scriptable_object_(scriptable_object), + plugin_message_loop_(plugin_message_loop), callback_message_loop_(callback_message_loop) { - CHECK(CurrentlyOnPluginThread()); + DCHECK(plugin_message_loop_->BelongsToCurrentThread()); } PepperXmppProxy::~PepperXmppProxy() { @@ -32,30 +33,25 @@ void PepperXmppProxy::DetachCallback() { } void PepperXmppProxy::SendIq(const std::string& request_xml) { - if (!CurrentlyOnPluginThread()) { - RunTaskOnPluginThread(NewRunnableMethod(this, - &PepperXmppProxy::SendIq, - request_xml)); + if (!plugin_message_loop_->BelongsToCurrentThread()) { + plugin_message_loop_->PostTask(FROM_HERE, base::Bind( + &PepperXmppProxy::SendIq, this, request_xml)); return; } - if (scriptable_object_) { + if (scriptable_object_) scriptable_object_->SendIq(request_xml); - } } void PepperXmppProxy::OnIq(const std::string& response_xml) { if (!callback_message_loop_->BelongsToCurrentThread()) { callback_message_loop_->PostTask( - FROM_HERE,NewRunnableMethod(this, - &PepperXmppProxy::OnIq, - response_xml)); + FROM_HERE, base::Bind(&PepperXmppProxy::OnIq, this, response_xml)); return; } - if (callback_) { + if (callback_) callback_->OnIq(response_xml); - } } } // namespace remoting diff --git a/remoting/client/plugin/pepper_xmpp_proxy.h b/remoting/client/plugin/pepper_xmpp_proxy.h index aca7f94..189572c 100644 --- a/remoting/client/plugin/pepper_xmpp_proxy.h +++ b/remoting/client/plugin/pepper_xmpp_proxy.h @@ -21,6 +21,7 @@ class PepperXmppProxy : public XmppProxy { public: PepperXmppProxy( base::WeakPtr<ChromotingScriptableObject> scriptable_object, + base::MessageLoopProxy* plugin_message_loop, base::MessageLoopProxy* callback_message_loop); // Registered the callback class with this object. @@ -43,6 +44,7 @@ class PepperXmppProxy : public XmppProxy { base::WeakPtr<ChromotingScriptableObject> scriptable_object_; + scoped_refptr<base::MessageLoopProxy> plugin_message_loop_; scoped_refptr<base::MessageLoopProxy> callback_message_loop_; // Must only be access on callback_message_loop_. diff --git a/remoting/remoting.gyp b/remoting/remoting.gyp index 7fb27f0..91eed9a 100644 --- a/remoting/remoting.gyp +++ b/remoting/remoting.gyp @@ -145,6 +145,8 @@ 'client/plugin/pepper_input_handler.h', 'client/plugin/pepper_port_allocator_session.cc', 'client/plugin/pepper_port_allocator_session.h', + 'client/plugin/pepper_plugin_thread_delegate.cc', + 'client/plugin/pepper_plugin_thread_delegate.h', 'client/plugin/pepper_view.cc', 'client/plugin/pepper_view.h', 'client/plugin/pepper_view_proxy.cc', |