summaryrefslogtreecommitdiffstats
path: root/content/common
diff options
context:
space:
mode:
authorreveman <reveman@chromium.org>2015-10-29 16:56:31 -0700
committerCommit bot <commit-bot@chromium.org>2015-10-29 23:57:07 +0000
commitd13710832e9d0e6302cf8388cda94a7a780d8664 (patch)
tree64f3f13fd7a0d645d0338acd83f93e8f47b73695 /content/common
parentd3839f0b456e261c7b10c45898658d0790ccd571 (diff)
downloadchromium_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')
-rw-r--r--content/common/host_discardable_shared_memory_manager.cc15
-rw-r--r--content/common/host_discardable_shared_memory_manager.h5
-rw-r--r--content/common/host_discardable_shared_memory_manager_unittest.cc46
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