diff options
author | reveman <reveman@chromium.org> | 2015-10-29 16:56:31 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-10-29 23:57:07 +0000 |
commit | d13710832e9d0e6302cf8388cda94a7a780d8664 (patch) | |
tree | 64f3f13fd7a0d645d0338acd83f93e8f47b73695 /content/common | |
parent | d3839f0b456e261c7b10c45898658d0790ccd571 (diff) | |
download | chromium_src-d13710832e9d0e6302cf8388cda94a7a780d8664.zip chromium_src-d13710832e9d0e6302cf8388cda94a7a780d8664.tar.gz chromium_src-d13710832e9d0e6302cf8388cda94a7a780d8664.tar.bz2 |
content: Always run EnforceMemoryPolicy() callbacks on the same thread.
This allows ::ScheduleEnforceMemoryPolicy() to be called on
a worker thread without a message loop.
BUG=549274
TEST=content_unittests --gtest_filter=HostDiscardableSharedMemoryManagerScheduleEnforceMemoryPolicyTest.SetMemoryLimitOnSimpleThread
Review URL: https://codereview.chromium.org/1430743002
Cr-Commit-Position: refs/heads/master@{#356989}
Diffstat (limited to 'content/common')
3 files changed, 62 insertions, 4 deletions
diff --git a/content/common/host_discardable_shared_memory_manager.cc b/content/common/host_discardable_shared_memory_manager.cc index 5391361..2ea9821 100644 --- a/content/common/host_discardable_shared_memory_manager.cc +++ b/content/common/host_discardable_shared_memory_manager.cc @@ -123,9 +123,17 @@ HostDiscardableSharedMemoryManager::HostDiscardableSharedMemoryManager() memory_pressure_listener_(new base::MemoryPressureListener( base::Bind(&HostDiscardableSharedMemoryManager::OnMemoryPressure, base::Unretained(this)))), + // Current thread might not have a task runner in tests. + enforce_memory_policy_task_runner_( + base::ThreadTaskRunnerHandle::IsSet() + ? base::ThreadTaskRunnerHandle::Get() + : nullptr), enforce_memory_policy_pending_(false), weak_ptr_factory_(this) { DCHECK_NE(memory_limit_, 0u); + enforce_memory_policy_callback_ = + base::Bind(&HostDiscardableSharedMemoryManager::EnforceMemoryPolicy, + weak_ptr_factory_.GetWeakPtr()); base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( this); } @@ -486,10 +494,9 @@ void HostDiscardableSharedMemoryManager::ScheduleEnforceMemoryPolicy() { return; enforce_memory_policy_pending_ = true; - base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( - FROM_HERE, - base::Bind(&HostDiscardableSharedMemoryManager::EnforceMemoryPolicy, - weak_ptr_factory_.GetWeakPtr()), + DCHECK(enforce_memory_policy_task_runner_); + enforce_memory_policy_task_runner_->PostDelayedTask( + FROM_HERE, enforce_memory_policy_callback_, base::TimeDelta::FromMilliseconds(kEnforceMemoryPolicyDelayMs)); } diff --git a/content/common/host_discardable_shared_memory_manager.h b/content/common/host_discardable_shared_memory_manager.h index 00ba1b5..aa5349a 100644 --- a/content/common/host_discardable_shared_memory_manager.h +++ b/content/common/host_discardable_shared_memory_manager.h @@ -7,6 +7,7 @@ #include <vector> +#include "base/callback.h" #include "base/containers/hash_tables.h" #include "base/format_macros.h" #include "base/memory/discardable_memory_allocator.h" @@ -17,6 +18,7 @@ #include "base/memory/weak_ptr.h" #include "base/process/process_handle.h" #include "base/synchronization/lock.h" +#include "base/thread_task_runner_handle.h" #include "base/trace_event/memory_dump_provider.h" #include "content/common/content_export.h" @@ -127,6 +129,9 @@ class CONTENT_EXPORT HostDiscardableSharedMemoryManager size_t memory_limit_; size_t bytes_allocated_; scoped_ptr<base::MemoryPressureListener> memory_pressure_listener_; + scoped_refptr<base::SingleThreadTaskRunner> + enforce_memory_policy_task_runner_; + base::Closure enforce_memory_policy_callback_; bool enforce_memory_policy_pending_; base::WeakPtrFactory<HostDiscardableSharedMemoryManager> weak_ptr_factory_; diff --git a/content/common/host_discardable_shared_memory_manager_unittest.cc b/content/common/host_discardable_shared_memory_manager_unittest.cc index 8f09ef0..3adbc72 100644 --- a/content/common/host_discardable_shared_memory_manager_unittest.cc +++ b/content/common/host_discardable_shared_memory_manager_unittest.cc @@ -4,6 +4,7 @@ #include "content/common/host_discardable_shared_memory_manager.h" +#include "base/threading/simple_thread.h" #include "content/public/common/child_process_host.h" #include "testing/gtest/include/gtest/gtest.h" @@ -232,5 +233,50 @@ TEST_F(HostDiscardableSharedMemoryManagerTest, memory2.Unlock(0, 0); } +class HostDiscardableSharedMemoryManagerScheduleEnforceMemoryPolicyTest + : public testing::Test { + protected: + // Overridden from testing::Test: + void SetUp() override { + manager_.reset(new HostDiscardableSharedMemoryManager); + } + + // This test requires a message loop. + base::MessageLoop message_loop_; + scoped_ptr<HostDiscardableSharedMemoryManager> manager_; +}; + +class SetMemoryLimitRunner : public base::DelegateSimpleThread::Delegate { + public: + SetMemoryLimitRunner(HostDiscardableSharedMemoryManager* manager, + size_t limit) + : manager_(manager), limit_(limit) {} + ~SetMemoryLimitRunner() override {} + + void Run() override { manager_->SetMemoryLimit(limit_); } + + private: + HostDiscardableSharedMemoryManager* const manager_; + const size_t limit_; +}; + +TEST_F(HostDiscardableSharedMemoryManagerScheduleEnforceMemoryPolicyTest, + SetMemoryLimitOnSimpleThread) { + const int kDataSize = 1024; + + base::SharedMemoryHandle shared_handle; + manager_->AllocateLockedDiscardableSharedMemoryForChild( + base::GetCurrentProcessHandle(), ChildProcessHost::kInvalidUniqueID, + kDataSize, 0, &shared_handle); + ASSERT_TRUE(base::SharedMemory::IsHandleValid(shared_handle)); + + // Set the memory limit to a value that will require EnforceMemoryPolicy() + // to be schedule on a thread without a message loop. + SetMemoryLimitRunner runner(manager_.get(), kDataSize - 1); + base::DelegateSimpleThread thread(&runner, "memory_limit_setter"); + thread.Start(); + thread.Join(); +} + } // namespace } // namespace content |