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

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: - 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
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 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 68
69 } // namespace 69 } // namespace
70 70
71 // This flag blocks LOGs to the UI if we're already in the middle of logging 71 // This flag blocks LOGs to the UI if we're already in the middle of logging
72 // to the UI. This prevents a potential infinite loop if we encounter an error 72 // to the UI. This prevents a potential infinite loop if we encounter an error
73 // while sending the log message to the UI. 73 // while sending the log message to the UI.
74 static bool g_logging_to_plugin = false; 74 static bool g_logging_to_plugin = false;
75 static HostNPScriptObject* g_logging_scriptable_object = NULL; 75 static HostNPScriptObject* g_logging_scriptable_object = NULL;
76 static logging::LogMessageHandlerFunction g_logging_old_handler = NULL; 76 static logging::LogMessageHandlerFunction g_logging_old_handler = NULL;
77 77
78 HostNPScriptObject::HostNPScriptObject(NPP plugin, NPObject* parent) 78 HostNPScriptObject::HostNPScriptObject(
79 NPP plugin,
80 NPObject* parent,
81 PluginMessageLoopProxy::Delegate* plugin_thread_delegate)
79 : plugin_(plugin), 82 : plugin_(plugin),
80 parent_(parent), 83 parent_(parent),
81 state_(kDisconnected), 84 state_(kDisconnected),
82 log_debug_info_func_(NULL), 85 log_debug_info_func_(NULL),
83 on_state_changed_func_(NULL), 86 on_state_changed_func_(NULL),
84 np_thread_id_(base::PlatformThread::CurrentId()), 87 np_thread_id_(base::PlatformThread::CurrentId()),
88 plugin_message_loop_proxy_(
89 new PluginMessageLoopProxy(plugin_thread_delegate)),
90 host_context_(plugin_message_loop_proxy_),
85 failed_login_attempts_(0), 91 failed_login_attempts_(0),
86 disconnected_event_(true, false) { 92 disconnected_event_(true, false) {
87 // Set up log message handler. 93 // Set up log message handler.
88 // Note that this approach doesn't quite support having multiple instances 94 // Note that this approach doesn't quite support having multiple instances
89 // of Chromoting running. In that case, the most recently opened tab will 95 // of Chromoting running. In that case, the most recently opened tab will
90 // grab all the debug log messages, and when any Chromoting tab is closed 96 // grab all the debug log messages, and when any Chromoting tab is closed
91 // the logging handler will go away. 97 // the logging handler will go away.
92 // Since having multiple Chromoting tabs is not a primary use case, and this 98 // Since having multiple Chromoting tabs is not a primary use case, and this
93 // is just debug logging, we're punting improving debug log support for that 99 // is just debug logging, we're punting improving debug log support for that
94 // case. 100 // case.
95 if (g_logging_old_handler == NULL) 101 if (g_logging_old_handler == NULL)
96 g_logging_old_handler = logging::GetLogMessageHandler(); 102 g_logging_old_handler = logging::GetLogMessageHandler();
97 logging::SetLogMessageHandler(&LogToUI); 103 logging::SetLogMessageHandler(&LogToUI);
98 g_logging_scriptable_object = this; 104 g_logging_scriptable_object = this;
99
100 VLOG(2) << "HostNPScriptObject";
101 host_context_.SetUITaskPostFunction(base::Bind(
102 &HostNPScriptObject::PostTaskToNPThread, base::Unretained(this)));
103 } 105 }
104 106
105 HostNPScriptObject::~HostNPScriptObject() { 107 HostNPScriptObject::~HostNPScriptObject() {
106 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); 108 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_);
107 109
108 // Shutdown DesktopEnvironment first so that it doesn't try to post 110 // Shutdown DesktopEnvironment first so that it doesn't try to post
109 // tasks on the UI thread while we are stopping the host. 111 // tasks on the UI thread while we are stopping the host.
110 desktop_environment_->Shutdown(); 112 desktop_environment_->Shutdown();
111 113
112 logging::SetLogMessageHandler(g_logging_old_handler); 114 logging::SetLogMessageHandler(g_logging_old_handler);
113 g_logging_old_handler = NULL; 115 g_logging_old_handler = NULL;
114 g_logging_scriptable_object = NULL; 116 g_logging_scriptable_object = NULL;
115 117
118 plugin_message_loop_proxy_->Detach();
119
116 // Disconnect synchronously. We cannot disconnect asynchronously 120 // Disconnect synchronously. We cannot disconnect asynchronously
117 // here because |host_context_| needs to be stopped on the plugin 121 // here because |host_context_| needs to be stopped on the plugin
118 // thread, but the plugin thread may not exist after the instance 122 // thread, but the plugin thread may not exist after the instance
119 // is destroyed. 123 // is destroyed.
120 destructing_.Set();
121 disconnected_event_.Reset(); 124 disconnected_event_.Reset();
122 DisconnectInternal(); 125 DisconnectInternal();
123 disconnected_event_.Wait(); 126 disconnected_event_.Wait();
124 127
125 // Stop all threads. 128 // Stop all threads.
126 host_context_.Stop(); 129 host_context_.Stop();
127 130
128 if (log_debug_info_func_) { 131 if (log_debug_info_func_) {
129 g_npnetscape_funcs->releaseobject(log_debug_info_func_); 132 g_npnetscape_funcs->releaseobject(log_debug_info_func_);
130 } 133 }
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after
507 access_code_lifetime_ = lifetime; 510 access_code_lifetime_ = lifetime;
508 511
509 // Tell the ChromotingHost the access code, to use as shared-secret. 512 // Tell the ChromotingHost the access code, to use as shared-secret.
510 host_->set_access_code(access_code_); 513 host_->set_access_code(access_code_);
511 514
512 // Let the caller know that life is good. 515 // Let the caller know that life is good.
513 OnStateChanged(kReceivedAccessCode); 516 OnStateChanged(kReceivedAccessCode);
514 } 517 }
515 518
516 void HostNPScriptObject::OnStateChanged(State state) { 519 void HostNPScriptObject::OnStateChanged(State state) {
517 if (destructing_.IsSet()) 520 if (!plugin_message_loop_proxy_->BelongsToCurrentThread()) {
518 return; 521 plugin_message_loop_proxy_->PostTask(
519
520 if (!host_context_.IsUIThread()) {
521 host_context_.PostTaskToUIThread(
522 FROM_HERE, base::Bind(&HostNPScriptObject::OnStateChanged, 522 FROM_HERE, base::Bind(&HostNPScriptObject::OnStateChanged,
523 base::Unretained(this), state)); 523 base::Unretained(this), state));
524 return; 524 return;
525 } 525 }
526 state_ = state; 526 state_ = state;
527 if (on_state_changed_func_) { 527 if (on_state_changed_func_) {
528 VLOG(2) << "Calling state changed " << state; 528 VLOG(2) << "Calling state changed " << state;
529 bool is_good = InvokeAndIgnoreResult(on_state_changed_func_, NULL, 0); 529 bool is_good = InvokeAndIgnoreResult(on_state_changed_func_, NULL, 0);
530 LOG_IF(ERROR, !is_good) << "OnStateChanged failed"; 530 LOG_IF(ERROR, !is_good) << "OnStateChanged failed";
531 } 531 }
(...skipping 13 matching lines...) Expand all
545 message += (str.c_str() + message_start); 545 message += (str.c_str() + message_start);
546 g_logging_scriptable_object->LogDebugInfo(message); 546 g_logging_scriptable_object->LogDebugInfo(message);
547 g_logging_to_plugin = false; 547 g_logging_to_plugin = false;
548 } 548 }
549 if (g_logging_old_handler) 549 if (g_logging_old_handler)
550 return (g_logging_old_handler)(severity, file, line, message_start, str); 550 return (g_logging_old_handler)(severity, file, line, message_start, str);
551 return false; 551 return false;
552 } 552 }
553 553
554 void HostNPScriptObject::LogDebugInfo(const std::string& message) { 554 void HostNPScriptObject::LogDebugInfo(const std::string& message) {
555 if (destructing_.IsSet()) 555 if (!plugin_message_loop_proxy_->BelongsToCurrentThread()) {
556 return; 556 plugin_message_loop_proxy_->PostTask(
557
558 if (!host_context_.IsUIThread()) {
559 host_context_.PostTaskToUIThread(
560 FROM_HERE, base::Bind(&HostNPScriptObject::LogDebugInfo, 557 FROM_HERE, base::Bind(&HostNPScriptObject::LogDebugInfo,
561 base::Unretained(this), message)); 558 base::Unretained(this), message));
562 return; 559 return;
563 } 560 }
564 561
565 if (log_debug_info_func_) { 562 if (log_debug_info_func_) {
566 NPVariant log_message; 563 NPVariant log_message;
567 STRINGZ_TO_NPVARIANT(message.c_str(), log_message); 564 STRINGZ_TO_NPVARIANT(message.c_str(), log_message);
568 bool is_good = InvokeAndIgnoreResult(log_debug_info_func_, 565 bool is_good = InvokeAndIgnoreResult(log_debug_info_func_,
569 &log_message, 1); 566 &log_message, 1);
(...skipping 11 matching lines...) Expand all
581 const NPVariant* args, 578 const NPVariant* args,
582 uint32_t argCount) { 579 uint32_t argCount) {
583 NPVariant np_result; 580 NPVariant np_result;
584 bool is_good = g_npnetscape_funcs->invokeDefault(plugin_, func, args, 581 bool is_good = g_npnetscape_funcs->invokeDefault(plugin_, func, args,
585 argCount, &np_result); 582 argCount, &np_result);
586 if (is_good) 583 if (is_good)
587 g_npnetscape_funcs->releasevariantvalue(&np_result); 584 g_npnetscape_funcs->releasevariantvalue(&np_result);
588 return is_good; 585 return is_good;
589 } 586 }
590 587
591 void HostNPScriptObject::PostTaskToNPThread(
592 const tracked_objects::Location& from_here, const base::Closure& task) {
593 // The NPAPI functions cannot make use of |from_here|, but this method is
594 // passed as a callback to ChromotingHostContext, so it needs to have the
595 // appropriate signature.
596
597 // Copy task to the heap so that we can pass it to NPTaskSpringboard().
598 base::Closure* task_in_heap = new base::Closure(task);
599
600 // Can be called from any thread.
601 g_npnetscape_funcs->pluginthreadasynccall(plugin_, &NPTaskSpringboard,
602 task_in_heap);
603 }
604
605 // static
606 void HostNPScriptObject::NPTaskSpringboard(void* task) {
607 base::Closure* real_task = reinterpret_cast<base::Closure*>(task);
608 real_task->Run();
609 delete real_task;
610 }
611
612 } // namespace remoting 588 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698