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

Unified Diff: content/browser/memory/memory_pressure_controller.cc

Issue 1332583002: Architecture for cross-process memory notification suppressing (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Split patch Created 5 years, 3 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 side-by-side diff with in-line comments
Download patch
Index: content/browser/memory/memory_pressure_controller.cc
diff --git a/content/browser/memory/memory_pressure_controller.cc b/content/browser/memory/memory_pressure_controller.cc
new file mode 100644
index 0000000000000000000000000000000000000000..2793faebd3e8b659f0e9712b15cb83203f6bcdc0
--- /dev/null
+++ b/content/browser/memory/memory_pressure_controller.cc
@@ -0,0 +1,139 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/memory/memory_pressure_controller.h"
+
+#include "base/bind.h"
+#include "base/memory/memory_pressure_listener.h"
+#include "base/memory/ref_counted.h"
+#include "content/browser/memory/memory_message_filter.h"
+#include "content/public/browser/browser_thread.h"
+
+namespace content {
+namespace memory {
+
+MemoryPressureController::MemoryPressureController() {}
+
+MemoryPressureController::~MemoryPressureController() {}
+
+void MemoryPressureController::OnMemoryMessageFilterAdded(
+ MemoryMessageFilter* filter) {
+ if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
Primiano Tucci (use gerrit) 2015/09/16 09:11:50 Hmm why do you want this to live on the UI thread?
petrcermak 2015/09/16 18:14:26 Done (changed back to IO).
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&MemoryPressureController::OnMemoryMessageFilterAdded,
+ base::Unretained(this), make_scoped_refptr(filter)));
+ return;
+ }
+
+ DCHECK(memory_message_filters_.find(filter) == memory_message_filters_.end());
+ memory_message_filters_.insert(filter);
+
+ if (base::MemoryPressureListener::AreNotificationsSuppressed())
+ filter->SendSetPressureNotificationsSuppressed(true);
+}
+
+void MemoryPressureController::OnMemoryMessageFilterRemoved(
+ MemoryMessageFilter* filter) {
+ if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&MemoryPressureController::OnMemoryMessageFilterRemoved,
+ base::Unretained(this), make_scoped_refptr(filter)));
+ return;
+ }
+
+ // Pretend we received a set notifications suppressed response from the
+ // child process in case we are waiting for one.
+ OnSetPressureNotificationsSuppressedResponse(filter);
+
+ DCHECK(memory_message_filters_.find(filter) != memory_message_filters_.end());
+ memory_message_filters_.erase(filter);
+}
+
+void MemoryPressureController::OnSetPressureNotificationsSuppressedResponse(
+ MemoryMessageFilter* filter) {
+ if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&MemoryPressureController::
+ OnSetPressureNotificationsSuppressedResponse,
+ base::Unretained(this), make_scoped_refptr(filter)));
+ return;
+ }
+
+ DCHECK(memory_message_filters_.find(filter) != memory_message_filters_.end());
+
+ // Ignore the response if we were not expecting it.
+ if (pending_set_pressure_notifications_suppressed_filters_.find(filter) ==
+ pending_set_pressure_notifications_suppressed_filters_.end())
+ return;
+
+ pending_set_pressure_notifications_suppressed_filters_.erase(filter);
+
+ // Do nothing if there are more pending acks.
+ if (!pending_set_pressure_notifications_suppressed_filters_.empty())
+ return;
+
+ if (!pending_set_pressure_notifications_suppressed_callback_.is_null()) {
+ pending_set_pressure_notifications_suppressed_callback_.Run(
+ true /* success */);
+ pending_set_pressure_notifications_suppressed_callback_.Reset();
+ }
+}
+
+// static
+base::LazyInstance<MemoryPressureController>::Leaky g_controller =
Primiano Tucci (use gerrit) 2015/09/16 09:11:50 out of curiosity why don't you use Singleton + Le
petrcermak 2015/09/16 18:14:26 Done (there wasn't any particular reason).
+ LAZY_INSTANCE_INITIALIZER;
+
+// static
+MemoryPressureController* MemoryPressureController::GetInstance() {
+ return &g_controller.Get();
+}
+
+void MemoryPressureController::SetPressureNotificationsSuppressedInAllProcesses(
+ bool suppressed,
+ const MemoryMessageCallback& callback) {
+ if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&MemoryPressureController::
+ SetPressureNotificationsSuppressedInAllProcesses,
+ base::Unretained(this), suppressed, callback));
+ return;
+ }
+
+ // Abort if another request is already in progress.
+ if (!pending_set_pressure_notifications_suppressed_filters_.empty()) {
+ DVLOG(1) << "Tried to set notifications suppressed in all processes while "
+ "the previous request hasn't finished yet";
+ if (!callback.is_null())
+ callback.Run(false /* success */);
+ return;
+ }
+
+ // Enable/disable suppressing memory notifications in the browser process.
+ base::MemoryPressureListener::SetNotificationsSuppressed(suppressed);
+
+ // If there are no child processes, we are done.
+ if (memory_message_filters_.empty()) {
+ if (!callback.is_null())
+ callback.Run(true /* success */);
+ return;
+ }
+
+ DCHECK(pending_set_pressure_notifications_suppressed_callback_.is_null());
+ pending_set_pressure_notifications_suppressed_filters_ =
+ memory_message_filters_;
+ pending_set_pressure_notifications_suppressed_callback_ = callback;
+
+ // Enable/disable suppressing memory notifications in all child processes.
+ for (MemoryMessageFilterSet::iterator it = memory_message_filters_.begin();
+ it != memory_message_filters_.end(); ++it) {
+ it->get()->SendSetPressureNotificationsSuppressed(suppressed);
+ }
+}
+
+} // namespace memory
+} // namespace content

Powered by Google App Engine
This is Rietveld 408576698