Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: remoting/host/plugin/host_script_object.cc

Issue 7635030: Add PluginMessageLoopProxy and use it for Host plugin UI thread. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix release build break Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « remoting/host/plugin/host_script_object.h ('k') | remoting/host/simple_host_process.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "remoting/host/plugin/host_script_object.h" 5 #include "remoting/host/plugin/host_script_object.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/message_loop.h" 8 #include "base/message_loop.h"
9 #include "base/message_loop_proxy.h" 9 #include "base/message_loop_proxy.h"
10 #include "base/threading/platform_thread.h" 10 #include "base/threading/platform_thread.h"
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 71
72 } // namespace 72 } // namespace
73 73
74 // This flag blocks LOGs to the UI if we're already in the middle of logging 74 // This flag blocks LOGs to the UI if we're already in the middle of logging
75 // to the UI. This prevents a potential infinite loop if we encounter an error 75 // to the UI. This prevents a potential infinite loop if we encounter an error
76 // while sending the log message to the UI. 76 // while sending the log message to the UI.
77 static bool g_logging_to_plugin = false; 77 static bool g_logging_to_plugin = false;
78 static HostNPScriptObject* g_logging_scriptable_object = NULL; 78 static HostNPScriptObject* g_logging_scriptable_object = NULL;
79 static logging::LogMessageHandlerFunction g_logging_old_handler = NULL; 79 static logging::LogMessageHandlerFunction g_logging_old_handler = NULL;
80 80
81 HostNPScriptObject::HostNPScriptObject(NPP plugin, NPObject* parent) 81 HostNPScriptObject::HostNPScriptObject(
82 NPP plugin,
83 NPObject* parent,
84 PluginMessageLoopProxy::Delegate* plugin_thread_delegate)
82 : plugin_(plugin), 85 : plugin_(plugin),
83 parent_(parent), 86 parent_(parent),
84 state_(kDisconnected), 87 state_(kDisconnected),
85 np_thread_id_(base::PlatformThread::CurrentId()), 88 np_thread_id_(base::PlatformThread::CurrentId()),
89 plugin_message_loop_proxy_(
90 new PluginMessageLoopProxy(plugin_thread_delegate)),
91 host_context_(plugin_message_loop_proxy_),
86 failed_login_attempts_(0), 92 failed_login_attempts_(0),
87 disconnected_event_(true, false), 93 disconnected_event_(true, false),
88 nat_traversal_enabled_(false), 94 nat_traversal_enabled_(false),
89 policy_received_(false) { 95 policy_received_(false) {
90 // Set up log message handler. 96 // Set up log message handler.
91 // Note that this approach doesn't quite support having multiple instances 97 // Note that this approach doesn't quite support having multiple instances
92 // of Chromoting running. In that case, the most recently opened tab will 98 // of Chromoting running. In that case, the most recently opened tab will
93 // grab all the debug log messages, and when any Chromoting tab is closed 99 // grab all the debug log messages, and when any Chromoting tab is closed
94 // the logging handler will go away. 100 // the logging handler will go away.
95 // Since having multiple Chromoting tabs is not a primary use case, and this 101 // Since having multiple Chromoting tabs is not a primary use case, and this
96 // is just debug logging, we're punting improving debug log support for that 102 // is just debug logging, we're punting improving debug log support for that
97 // case. 103 // case.
98 if (g_logging_old_handler == NULL) 104 if (g_logging_old_handler == NULL)
99 g_logging_old_handler = logging::GetLogMessageHandler(); 105 g_logging_old_handler = logging::GetLogMessageHandler();
100 logging::SetLogMessageHandler(&LogToUI); 106 logging::SetLogMessageHandler(&LogToUI);
101 g_logging_scriptable_object = this; 107 g_logging_scriptable_object = this;
102
103 VLOG(2) << "HostNPScriptObject";
104 host_context_.SetUITaskPostFunction(base::Bind(
105 &HostNPScriptObject::PostTaskToNPThread, base::Unretained(this)));
106 } 108 }
107 109
108 HostNPScriptObject::~HostNPScriptObject() { 110 HostNPScriptObject::~HostNPScriptObject() {
109 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); 111 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_);
110 112
111 // Shutdown DesktopEnvironment first so that it doesn't try to post 113 // Shutdown DesktopEnvironment first so that it doesn't try to post
112 // tasks on the UI thread while we are stopping the host. 114 // tasks on the UI thread while we are stopping the host.
113 desktop_environment_->Shutdown(); 115 desktop_environment_->Shutdown();
114 116
115 logging::SetLogMessageHandler(g_logging_old_handler); 117 logging::SetLogMessageHandler(g_logging_old_handler);
116 g_logging_old_handler = NULL; 118 g_logging_old_handler = NULL;
117 g_logging_scriptable_object = NULL; 119 g_logging_scriptable_object = NULL;
118 120
121 plugin_message_loop_proxy_->Detach();
122
119 // Stop listening for policy updates. 123 // Stop listening for policy updates.
120 if (nat_policy_.get()) { 124 if (nat_policy_.get()) {
121 base::WaitableEvent nat_policy_stopped_(true, false); 125 base::WaitableEvent nat_policy_stopped_(true, false);
122 nat_policy_->StopWatching(&nat_policy_stopped_); 126 nat_policy_->StopWatching(&nat_policy_stopped_);
123 nat_policy_stopped_.Wait(); 127 nat_policy_stopped_.Wait();
124 nat_policy_.reset(); 128 nat_policy_.reset();
125 } 129 }
126 130
127 // Disconnect synchronously. We cannot disconnect asynchronously 131 // Disconnect synchronously. We cannot disconnect asynchronously
128 // here because |host_context_| needs to be stopped on the plugin 132 // here because |host_context_| needs to be stopped on the plugin
129 // thread, but the plugin thread may not exist after the instance 133 // thread, but the plugin thread may not exist after the instance
130 // is destroyed. 134 // is destroyed.
131 destructing_.Set();
awong 2011/08/18 01:49:14 Doesn't this still need to be around Sergey?
132 disconnected_event_.Reset(); 135 disconnected_event_.Reset();
133 DisconnectInternal(); 136 DisconnectInternal();
134 disconnected_event_.Wait(); 137 disconnected_event_.Wait();
135 138
136 // Stop all threads. 139 // Stop all threads.
137 host_context_.Stop(); 140 host_context_.Stop();
138 } 141 }
139 142
140 bool HostNPScriptObject::Init() { 143 bool HostNPScriptObject::Init() {
141 VLOG(2) << "Init"; 144 VLOG(2) << "Init";
(...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after
570 access_code_lifetime_ = lifetime; 573 access_code_lifetime_ = lifetime;
571 574
572 // Tell the ChromotingHost the access code, to use as shared-secret. 575 // Tell the ChromotingHost the access code, to use as shared-secret.
573 host_->set_access_code(access_code_); 576 host_->set_access_code(access_code_);
574 577
575 // Let the caller know that life is good. 578 // Let the caller know that life is good.
576 OnStateChanged(kReceivedAccessCode); 579 OnStateChanged(kReceivedAccessCode);
577 } 580 }
578 581
579 void HostNPScriptObject::OnStateChanged(State state) { 582 void HostNPScriptObject::OnStateChanged(State state) {
580 if (destructing_.IsSet()) 583 if (!plugin_message_loop_proxy_->BelongsToCurrentThread()) {
581 return; 584 plugin_message_loop_proxy_->PostTask(
582
583 if (!host_context_.IsUIThread()) {
584 host_context_.PostTaskToUIThread(
585 FROM_HERE, base::Bind(&HostNPScriptObject::OnStateChanged, 585 FROM_HERE, base::Bind(&HostNPScriptObject::OnStateChanged,
586 base::Unretained(this), state)); 586 base::Unretained(this), state));
587 return; 587 return;
588 } 588 }
589 state_ = state; 589 state_ = state;
590 if (on_state_changed_func_.get()) { 590 if (on_state_changed_func_.get()) {
591 VLOG(2) << "Calling state changed " << state; 591 VLOG(2) << "Calling state changed " << state;
592 bool is_good = InvokeAndIgnoreResult(on_state_changed_func_.get(), NULL, 0); 592 bool is_good = InvokeAndIgnoreResult(on_state_changed_func_.get(), NULL, 0);
593 LOG_IF(ERROR, !is_good) << "OnStateChanged failed"; 593 LOG_IF(ERROR, !is_good) << "OnStateChanged failed";
594 } 594 }
(...skipping 13 matching lines...) Expand all
608 message += (str.c_str() + message_start); 608 message += (str.c_str() + message_start);
609 g_logging_scriptable_object->LogDebugInfo(message); 609 g_logging_scriptable_object->LogDebugInfo(message);
610 g_logging_to_plugin = false; 610 g_logging_to_plugin = false;
611 } 611 }
612 if (g_logging_old_handler) 612 if (g_logging_old_handler)
613 return (g_logging_old_handler)(severity, file, line, message_start, str); 613 return (g_logging_old_handler)(severity, file, line, message_start, str);
614 return false; 614 return false;
615 } 615 }
616 616
617 void HostNPScriptObject::LogDebugInfo(const std::string& message) { 617 void HostNPScriptObject::LogDebugInfo(const std::string& message) {
618 if (destructing_.IsSet()) 618 if (!plugin_message_loop_proxy_->BelongsToCurrentThread()) {
619 return; 619 plugin_message_loop_proxy_->PostTask(
620
621 if (!host_context_.IsUIThread()) {
622 host_context_.PostTaskToUIThread(
623 FROM_HERE, base::Bind(&HostNPScriptObject::LogDebugInfo, 620 FROM_HERE, base::Bind(&HostNPScriptObject::LogDebugInfo,
624 base::Unretained(this), message)); 621 base::Unretained(this), message));
625 return; 622 return;
626 } 623 }
627 624
628 if (log_debug_info_func_.get()) { 625 if (log_debug_info_func_.get()) {
629 NPVariant log_message; 626 NPVariant log_message;
630 STRINGZ_TO_NPVARIANT(message.c_str(), log_message); 627 STRINGZ_TO_NPVARIANT(message.c_str(), log_message);
631 bool is_good = InvokeAndIgnoreResult(log_debug_info_func_.get(), 628 bool is_good = InvokeAndIgnoreResult(log_debug_info_func_.get(),
632 &log_message, 1); 629 &log_message, 1);
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
697 const NPVariant* args, 694 const NPVariant* args,
698 uint32_t argCount) { 695 uint32_t argCount) {
699 NPVariant np_result; 696 NPVariant np_result;
700 bool is_good = g_npnetscape_funcs->invokeDefault(plugin_, func, args, 697 bool is_good = g_npnetscape_funcs->invokeDefault(plugin_, func, args,
701 argCount, &np_result); 698 argCount, &np_result);
702 if (is_good) 699 if (is_good)
703 g_npnetscape_funcs->releasevariantvalue(&np_result); 700 g_npnetscape_funcs->releasevariantvalue(&np_result);
704 return is_good; 701 return is_good;
705 } 702 }
706 703
707 void HostNPScriptObject::PostTaskToNPThread(
708 const tracked_objects::Location& from_here, const base::Closure& task) {
709 // The NPAPI functions cannot make use of |from_here|, but this method is
710 // passed as a callback to ChromotingHostContext, so it needs to have the
711 // appropriate signature.
712
713 // Copy task to the heap so that we can pass it to NPTaskSpringboard().
714 base::Closure* task_in_heap = new base::Closure(task);
715
716 // Can be called from any thread.
717 g_npnetscape_funcs->pluginthreadasynccall(plugin_, &NPTaskSpringboard,
718 task_in_heap);
719 }
720
721 // static
722 void HostNPScriptObject::NPTaskSpringboard(void* task) {
723 base::Closure* real_task = reinterpret_cast<base::Closure*>(task);
724 real_task->Run();
725 delete real_task;
726 }
727
728 } // namespace remoting 704 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/host/plugin/host_script_object.h ('k') | remoting/host/simple_host_process.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698