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

Side by Side 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/browser/memory/memory_pressure_controller.h"
6
7 #include "base/bind.h"
8 #include "base/memory/memory_pressure_listener.h"
9 #include "base/memory/ref_counted.h"
10 #include "content/browser/memory/memory_message_filter.h"
11 #include "content/public/browser/browser_thread.h"
12
13 namespace content {
14 namespace memory {
15
16 MemoryPressureController::MemoryPressureController() {}
17
18 MemoryPressureController::~MemoryPressureController() {}
19
20 void MemoryPressureController::OnMemoryMessageFilterAdded(
21 MemoryMessageFilter* filter) {
22 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).
23 BrowserThread::PostTask(
24 BrowserThread::UI, FROM_HERE,
25 base::Bind(&MemoryPressureController::OnMemoryMessageFilterAdded,
26 base::Unretained(this), make_scoped_refptr(filter)));
27 return;
28 }
29
30 DCHECK(memory_message_filters_.find(filter) == memory_message_filters_.end());
31 memory_message_filters_.insert(filter);
32
33 if (base::MemoryPressureListener::AreNotificationsSuppressed())
34 filter->SendSetPressureNotificationsSuppressed(true);
35 }
36
37 void MemoryPressureController::OnMemoryMessageFilterRemoved(
38 MemoryMessageFilter* filter) {
39 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
40 BrowserThread::PostTask(
41 BrowserThread::UI, FROM_HERE,
42 base::Bind(&MemoryPressureController::OnMemoryMessageFilterRemoved,
43 base::Unretained(this), make_scoped_refptr(filter)));
44 return;
45 }
46
47 // Pretend we received a set notifications suppressed response from the
48 // child process in case we are waiting for one.
49 OnSetPressureNotificationsSuppressedResponse(filter);
50
51 DCHECK(memory_message_filters_.find(filter) != memory_message_filters_.end());
52 memory_message_filters_.erase(filter);
53 }
54
55 void MemoryPressureController::OnSetPressureNotificationsSuppressedResponse(
56 MemoryMessageFilter* filter) {
57 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
58 BrowserThread::PostTask(
59 BrowserThread::UI, FROM_HERE,
60 base::Bind(&MemoryPressureController::
61 OnSetPressureNotificationsSuppressedResponse,
62 base::Unretained(this), make_scoped_refptr(filter)));
63 return;
64 }
65
66 DCHECK(memory_message_filters_.find(filter) != memory_message_filters_.end());
67
68 // Ignore the response if we were not expecting it.
69 if (pending_set_pressure_notifications_suppressed_filters_.find(filter) ==
70 pending_set_pressure_notifications_suppressed_filters_.end())
71 return;
72
73 pending_set_pressure_notifications_suppressed_filters_.erase(filter);
74
75 // Do nothing if there are more pending acks.
76 if (!pending_set_pressure_notifications_suppressed_filters_.empty())
77 return;
78
79 if (!pending_set_pressure_notifications_suppressed_callback_.is_null()) {
80 pending_set_pressure_notifications_suppressed_callback_.Run(
81 true /* success */);
82 pending_set_pressure_notifications_suppressed_callback_.Reset();
83 }
84 }
85
86 // static
87 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).
88 LAZY_INSTANCE_INITIALIZER;
89
90 // static
91 MemoryPressureController* MemoryPressureController::GetInstance() {
92 return &g_controller.Get();
93 }
94
95 void MemoryPressureController::SetPressureNotificationsSuppressedInAllProcesses(
96 bool suppressed,
97 const MemoryMessageCallback& callback) {
98 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
99 BrowserThread::PostTask(
100 BrowserThread::UI, FROM_HERE,
101 base::Bind(&MemoryPressureController::
102 SetPressureNotificationsSuppressedInAllProcesses,
103 base::Unretained(this), suppressed, callback));
104 return;
105 }
106
107 // Abort if another request is already in progress.
108 if (!pending_set_pressure_notifications_suppressed_filters_.empty()) {
109 DVLOG(1) << "Tried to set notifications suppressed in all processes while "
110 "the previous request hasn't finished yet";
111 if (!callback.is_null())
112 callback.Run(false /* success */);
113 return;
114 }
115
116 // Enable/disable suppressing memory notifications in the browser process.
117 base::MemoryPressureListener::SetNotificationsSuppressed(suppressed);
118
119 // If there are no child processes, we are done.
120 if (memory_message_filters_.empty()) {
121 if (!callback.is_null())
122 callback.Run(true /* success */);
123 return;
124 }
125
126 DCHECK(pending_set_pressure_notifications_suppressed_callback_.is_null());
127 pending_set_pressure_notifications_suppressed_filters_ =
128 memory_message_filters_;
129 pending_set_pressure_notifications_suppressed_callback_ = callback;
130
131 // Enable/disable suppressing memory notifications in all child processes.
132 for (MemoryMessageFilterSet::iterator it = memory_message_filters_.begin();
133 it != memory_message_filters_.end(); ++it) {
134 it->get()->SendSetPressureNotificationsSuppressed(suppressed);
135 }
136 }
137
138 } // namespace memory
139 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698