OLD | NEW |
---|---|
(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 | |
OLD | NEW |