diff options
author | scheib@chromium.org <scheib@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-12-18 23:37:11 +0000 |
---|---|---|
committer | scheib@chromium.org <scheib@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-12-18 23:37:11 +0000 |
commit | 200c9187bd8029de9a6d4665082c7bf358c62829 (patch) | |
tree | 45f7ff4ffd5df2a88dc1b99ccbbed8dbb01fee18 /ppapi | |
parent | 617342a4d1d8c52a788b35a44f0f504d39b2f2cd (diff) | |
download | chromium_src-200c9187bd8029de9a6d4665082c7bf358c62829.zip chromium_src-200c9187bd8029de9a6d4665082c7bf358c62829.tar.gz chromium_src-200c9187bd8029de9a6d4665082c7bf358c62829.tar.bz2 |
Keep NaCl plugins used in app background pages alive when active.
Activity in Native Client plugins results in IPC messages
sent to the BrowserPpapiHostImpl and routed to call
extensions::ProcessManager::KeepaliveImpulse.
Implementation patch, to be followed by tests. See:
https://codereview.chromium.org/111563006/ Tests.
https://codereview.chromium.org/105873003/ Cumulative patch.
Design doc:
https://docs.google.com/a/chromium.org/document/d/1mI0lS1rfAf-BAGLmWAEcWy37Xq9dOvgfMx8OqeUMXts/edit#
BUG=298339
Review URL: https://codereview.chromium.org/61063003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@241702 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi')
-rw-r--r-- | ppapi/proxy/plugin_globals.cc | 47 | ||||
-rw-r--r-- | ppapi/proxy/plugin_globals.h | 21 | ||||
-rw-r--r-- | ppapi/proxy/ppapi_messages.h | 3 | ||||
-rw-r--r-- | ppapi/shared_impl/ppapi_globals.cc | 3 | ||||
-rw-r--r-- | ppapi/shared_impl/ppapi_globals.h | 6 | ||||
-rw-r--r-- | ppapi/thunk/enter.cc | 5 |
6 files changed, 83 insertions, 2 deletions
diff --git a/ppapi/proxy/plugin_globals.cc b/ppapi/proxy/plugin_globals.cc index 59b5191..d34adf1 100644 --- a/ppapi/proxy/plugin_globals.cc +++ b/ppapi/proxy/plugin_globals.cc @@ -10,11 +10,18 @@ #include "ipc/ipc_sender.h" #include "ppapi/proxy/plugin_dispatcher.h" #include "ppapi/proxy/plugin_proxy_delegate.h" +#include "ppapi/proxy/ppapi_messages.h" #include "ppapi/proxy/ppb_message_loop_proxy.h" #include "ppapi/proxy/resource_reply_thread_registrar.h" #include "ppapi/shared_impl/proxy_lock.h" #include "ppapi/thunk/enter.h" +namespace { + +const int kKeepaliveThrottleIntervalDefault = 5000; + +} // namespace + namespace ppapi { namespace proxy { @@ -54,7 +61,11 @@ PluginGlobals::PluginGlobals() plugin_proxy_delegate_(NULL), callback_tracker_(new CallbackTracker), resource_reply_thread_registrar_( - new ResourceReplyThreadRegistrar(GetMainThreadMessageLoop())) { + new ResourceReplyThreadRegistrar(GetMainThreadMessageLoop())), + plugin_recently_active_(false), + keepalive_throttle_interval_milliseconds_( + kKeepaliveThrottleIntervalDefault), + weak_factory_(this) { DCHECK(!plugin_globals_); plugin_globals_ = this; @@ -71,7 +82,11 @@ PluginGlobals::PluginGlobals(PerThreadForTest per_thread_for_test) plugin_proxy_delegate_(NULL), callback_tracker_(new CallbackTracker), resource_reply_thread_registrar_( - new ResourceReplyThreadRegistrar(GetMainThreadMessageLoop())) { + new ResourceReplyThreadRegistrar(GetMainThreadMessageLoop())), + plugin_recently_active_(false), + keepalive_throttle_interval_milliseconds_( + kKeepaliveThrottleIntervalDefault), + weak_factory_(this) { DCHECK(!plugin_globals_); } @@ -165,6 +180,21 @@ base::TaskRunner* PluginGlobals::GetFileTaskRunner() { return file_thread_->message_loop_proxy(); } +void PluginGlobals::MarkPluginIsActive() { + if (!plugin_recently_active_) { + plugin_recently_active_ = true; + if (!GetBrowserSender() || !base::MessageLoop::current()) + return; + GetBrowserSender()->Send(new PpapiHostMsg_Keepalive()); + + GetMainThreadMessageLoop()->PostDelayedTask(FROM_HERE, + RunWhileLocked(base::Bind(&PluginGlobals::OnReleaseKeepaliveThrottle, + weak_factory_.GetWeakPtr())), + base::TimeDelta::FromMilliseconds( + keepalive_throttle_interval_milliseconds())); + } +} + IPC::Sender* PluginGlobals::GetBrowserSender() { if (!browser_sender_.get()) { browser_sender_.reset( @@ -195,9 +225,22 @@ MessageLoopResource* PluginGlobals::loop_for_main_thread() { return loop_for_main_thread_.get(); } +int PluginGlobals::keepalive_throttle_interval_milliseconds() const { + return keepalive_throttle_interval_milliseconds_; +} + +void PluginGlobals::set_keepalive_throttle_interval_milliseconds(int i) { + keepalive_throttle_interval_milliseconds_ = i; +} + bool PluginGlobals::IsPluginGlobals() const { return true; } +void PluginGlobals::OnReleaseKeepaliveThrottle() { + ppapi::ProxyLock::AssertAcquiredDebugOnly(); + plugin_recently_active_ = false; +} + } // namespace proxy } // namespace ppapi diff --git a/ppapi/proxy/plugin_globals.h b/ppapi/proxy/plugin_globals.h index 029e2d2..dac33b6 100644 --- a/ppapi/proxy/plugin_globals.h +++ b/ppapi/proxy/plugin_globals.h @@ -74,6 +74,7 @@ class PPAPI_PROXY_EXPORT PluginGlobals : public PpapiGlobals { const std::string& value) OVERRIDE; virtual MessageLoopShared* GetCurrentMessageLoop() OVERRIDE; base::TaskRunner* GetFileTaskRunner() OVERRIDE; + virtual void MarkPluginIsActive() OVERRIDE; // Returns the channel for sending to the browser. IPC::Sender* GetBrowserSender(); @@ -133,12 +134,21 @@ class PPAPI_PROXY_EXPORT PluginGlobals : public PpapiGlobals { return resource_reply_thread_registrar_.get(); } + // Interval to limit how many IPC messages are sent indicating that the plugin + // is active and should be kept alive. The value must be smaller than any + // threshold used to kill inactive plugins by the embedder host. + int keepalive_throttle_interval_milliseconds() const; + void set_keepalive_throttle_interval_milliseconds(int i); + private: class BrowserSender; // PpapiGlobals overrides. virtual bool IsPluginGlobals() const OVERRIDE; + // Locks the proxy lock and releases the throttle on keepalive IPC messages. + void OnReleaseKeepaliveThrottle(); + static PluginGlobals* plugin_globals_; PluginProxyDelegate* plugin_proxy_delegate_; @@ -167,6 +177,17 @@ class PPAPI_PROXY_EXPORT PluginGlobals : public PpapiGlobals { scoped_refptr<ResourceReplyThreadRegistrar> resource_reply_thread_registrar_; + // Indicates activity by the plugin. Used to monitor when a plugin can be + // shutdown due to idleness. Current needs do not require differentiating + // between idle state between multiple instances, if any are active they are + // all considered active. + bool plugin_recently_active_; + + int keepalive_throttle_interval_milliseconds_; + + // Member variables should appear before the WeakPtrFactory, see weak_ptr.h. + base::WeakPtrFactory<PluginGlobals> weak_factory_; + DISALLOW_COPY_AND_ASSIGN(PluginGlobals); }; diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h index 4b4fed8..086d42a 100644 --- a/ppapi/proxy/ppapi_messages.h +++ b/ppapi/proxy/ppapi_messages.h @@ -726,6 +726,9 @@ IPC_MESSAGE_ROUTED2(PpapiMsg_PPPVideoDecoder_NotifyError, PP_VideoDecodeError_Dev /* error */) #endif // !defined(OS_NACL) && !defined(NACL_WIN64) +// Reports to the browser that a plugin has been active. +IPC_MESSAGE_CONTROL0(PpapiHostMsg_Keepalive) + // ----------------------------------------------------------------------------- // These are from the plugin to the renderer. diff --git a/ppapi/shared_impl/ppapi_globals.cc b/ppapi/shared_impl/ppapi_globals.cc index 28ed2cf..f652f15 100644 --- a/ppapi/shared_impl/ppapi_globals.cc +++ b/ppapi/shared_impl/ppapi_globals.cc @@ -69,6 +69,9 @@ bool PpapiGlobals::IsPluginGlobals() const { return false; } +void PpapiGlobals::MarkPluginIsActive() { +} + // static PpapiGlobals* PpapiGlobals::GetThreadLocalPointer() { return tls_ppapi_globals_for_test.Pointer()->Get(); diff --git a/ppapi/shared_impl/ppapi_globals.h b/ppapi/shared_impl/ppapi_globals.h index 93ab299..d9be0387 100644 --- a/ppapi/shared_impl/ppapi_globals.h +++ b/ppapi/shared_impl/ppapi_globals.h @@ -128,6 +128,12 @@ class PPAPI_SHARED_EXPORT PpapiGlobals { virtual bool IsHostGlobals() const; virtual bool IsPluginGlobals() const; + // Records that the plugin is active. The plugin reports that it is active to + // containers that monitor and shutdown idle content such as background apps. + // This method only has an effect on the plugin process, calls from the + // renderer process will have no effect. + virtual void MarkPluginIsActive(); + private: // Return the thread-local pointer which is used only for unit testing. It // should always be NULL when running in production. It allows separate diff --git a/ppapi/thunk/enter.cc b/ppapi/thunk/enter.cc index 47889dd..2adc7f2 100644 --- a/ppapi/thunk/enter.cc +++ b/ppapi/thunk/enter.cc @@ -32,16 +32,19 @@ namespace subtle { EnterBase::EnterBase() : resource_(NULL), retval_(PP_OK) { + PpapiGlobals::Get()->MarkPluginIsActive(); } EnterBase::EnterBase(PP_Resource resource) : resource_(GetResource(resource)), retval_(PP_OK) { + PpapiGlobals::Get()->MarkPluginIsActive(); } EnterBase::EnterBase(PP_Instance instance, SingletonResourceID resource_id) : resource_(GetSingletonResource(instance, resource_id)), retval_(PP_OK) { + PpapiGlobals::Get()->MarkPluginIsActive(); } EnterBase::EnterBase(PP_Resource resource, @@ -49,6 +52,7 @@ EnterBase::EnterBase(PP_Resource resource, : resource_(GetResource(resource)), retval_(PP_OK) { callback_ = new TrackedCallback(resource_, callback); + PpapiGlobals::Get()->MarkPluginIsActive(); } EnterBase::EnterBase(PP_Instance instance, SingletonResourceID resource_id, @@ -59,6 +63,7 @@ EnterBase::EnterBase(PP_Instance instance, SingletonResourceID resource_id, if (!resource_) retval_ = PP_ERROR_BADARGUMENT; callback_ = new TrackedCallback(resource_, callback); + PpapiGlobals::Get()->MarkPluginIsActive(); } EnterBase::~EnterBase() { |