OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/memory/memory_pressure_controller.h" | 5 #include "content/browser/memory/memory_pressure_controller_impl.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "content/browser/memory/memory_message_filter.h" | 8 #include "content/browser/memory/memory_message_filter.h" |
9 #include "content/public/browser/browser_thread.h" | 9 #include "content/public/browser/browser_thread.h" |
10 | 10 |
11 namespace content { | 11 namespace content { |
12 | 12 |
13 MemoryPressureController::MemoryPressureController() {} | 13 MemoryPressureControllerImpl::MemoryPressureControllerImpl() {} |
14 | 14 |
15 MemoryPressureController::~MemoryPressureController() {} | 15 MemoryPressureControllerImpl::~MemoryPressureControllerImpl() {} |
16 | 16 |
17 void MemoryPressureController::OnMemoryMessageFilterAdded( | 17 void MemoryPressureControllerImpl::OnMemoryMessageFilterAdded( |
18 MemoryMessageFilter* filter) { | 18 MemoryMessageFilter* filter) { |
19 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 19 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
20 | 20 |
21 // Add the message filter to the set of all memory message filters and check | 21 // Add the message filter to the set of all memory message filters and check |
22 // that it wasn't there beforehand. | 22 // that it wasn't there beforehand. |
23 const bool success = | 23 const bool success = |
24 memory_message_filters_.insert( | 24 memory_message_filters_.insert( |
25 std::make_pair(filter->process_host(), filter)) | 25 std::make_pair(filter->process_host(), filter)) |
26 .second; | 26 .second; |
27 DCHECK(success); | 27 DCHECK(success); |
28 | 28 |
29 // There's no need to send a message to the child process if memory pressure | 29 // There's no need to send a message to the child process if memory pressure |
30 // notifications are not suppressed. | 30 // notifications are not suppressed. |
31 if (base::MemoryPressureListener::AreNotificationsSuppressed()) | 31 if (base::MemoryPressureListener::AreNotificationsSuppressed()) |
32 filter->SendSetPressureNotificationsSuppressed(true); | 32 filter->SendSetPressureNotificationsSuppressed(true); |
33 } | 33 } |
34 | 34 |
35 void MemoryPressureController::OnMemoryMessageFilterRemoved( | 35 void MemoryPressureControllerImpl::OnMemoryMessageFilterRemoved( |
36 MemoryMessageFilter* filter) { | 36 MemoryMessageFilter* filter) { |
37 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 37 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
38 | 38 |
39 // Remove the message filter from the set of all memory message filters, | 39 // Remove the message filter from the set of all memory message filters, |
40 // ensuring that it was there beforehand. | 40 // ensuring that it was there beforehand. |
41 auto it = memory_message_filters_.find(filter->process_host()); | 41 auto it = memory_message_filters_.find(filter->process_host()); |
42 DCHECK(it != memory_message_filters_.end()); | 42 DCHECK(it != memory_message_filters_.end()); |
43 DCHECK_EQ(filter, it->second); | 43 DCHECK_EQ(filter, it->second); |
44 memory_message_filters_.erase(it); | 44 memory_message_filters_.erase(it); |
45 } | 45 } |
46 | 46 |
47 // static | 47 // static |
48 MemoryPressureController* MemoryPressureController::GetInstance() { | 48 MemoryPressureControllerImpl* MemoryPressureControllerImpl::GetInstance() { |
49 return base::Singleton< | 49 return base::Singleton< |
50 MemoryPressureController, | 50 MemoryPressureControllerImpl, |
51 base::LeakySingletonTraits<MemoryPressureController>>::get(); | 51 base::LeakySingletonTraits<MemoryPressureControllerImpl>>::get(); |
52 } | 52 } |
53 | 53 |
54 void MemoryPressureController::SetPressureNotificationsSuppressedInAllProcesses( | 54 void |
| 55 MemoryPressureControllerImpl::SetPressureNotificationsSuppressedInAllProcesses( |
55 bool suppressed) { | 56 bool suppressed) { |
56 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { | 57 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { |
57 // Note that passing base::Unretained(this) is safe here because the | 58 // Note that passing base::Unretained(this) is safe here because the |
58 // controller is a leaky singleton. | 59 // controller is a leaky singleton. |
59 BrowserThread::PostTask( | 60 BrowserThread::PostTask( |
60 BrowserThread::IO, FROM_HERE, | 61 BrowserThread::IO, FROM_HERE, |
61 base::Bind(&MemoryPressureController:: | 62 base::Bind(&MemoryPressureControllerImpl:: |
62 SetPressureNotificationsSuppressedInAllProcesses, | 63 SetPressureNotificationsSuppressedInAllProcesses, |
63 base::Unretained(this), suppressed)); | 64 base::Unretained(this), suppressed)); |
64 return; | 65 return; |
65 } | 66 } |
66 | 67 |
67 // Enable/disable suppressing memory notifications in the browser process. | 68 // Enable/disable suppressing memory notifications in the browser process. |
68 base::MemoryPressureListener::SetNotificationsSuppressed(suppressed); | 69 base::MemoryPressureListener::SetNotificationsSuppressed(suppressed); |
69 | 70 |
70 // Enable/disable suppressing memory notifications in all child processes. | 71 // Enable/disable suppressing memory notifications in all child processes. |
71 for (const auto& filter_pair : memory_message_filters_) | 72 for (const auto& filter_pair : memory_message_filters_) |
72 filter_pair.second->SendSetPressureNotificationsSuppressed(suppressed); | 73 filter_pair.second->SendSetPressureNotificationsSuppressed(suppressed); |
73 } | 74 } |
74 | 75 |
75 void MemoryPressureController::SimulatePressureNotificationInAllProcesses( | 76 void MemoryPressureControllerImpl::SimulatePressureNotificationInAllProcesses( |
76 base::MemoryPressureListener::MemoryPressureLevel level) { | 77 base::MemoryPressureListener::MemoryPressureLevel level) { |
77 DCHECK_NE(level, base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE); | 78 DCHECK_NE(level, base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE); |
78 | 79 |
79 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { | 80 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { |
80 // Note that passing base::Unretained(this) is safe here because the | 81 // Note that passing base::Unretained(this) is safe here because the |
81 // controller is a leaky singleton. | 82 // controller is a leaky singleton. |
82 BrowserThread::PostTask( | 83 BrowserThread::PostTask( |
83 BrowserThread::IO, FROM_HERE, | 84 BrowserThread::IO, FROM_HERE, |
84 base::Bind(&MemoryPressureController:: | 85 base::Bind(&MemoryPressureControllerImpl:: |
85 SimulatePressureNotificationInAllProcesses, | 86 SimulatePressureNotificationInAllProcesses, |
86 base::Unretained(this), level)); | 87 base::Unretained(this), level)); |
87 return; | 88 return; |
88 } | 89 } |
89 | 90 |
90 // Simulate memory pressure notification in the browser process. | 91 // Simulate memory pressure notification in the browser process. |
91 base::MemoryPressureListener::SimulatePressureNotification(level); | 92 base::MemoryPressureListener::SimulatePressureNotification(level); |
92 | 93 |
93 // Simulate memory pressure notification in all child processes. | 94 // Simulate memory pressure notification in all child processes. |
94 for (const auto& filter_pair : memory_message_filters_) | 95 for (const auto& filter_pair : memory_message_filters_) |
95 filter_pair.second->SendSimulatePressureNotification(level); | 96 filter_pair.second->SendSimulatePressureNotification(level); |
96 } | 97 } |
97 | 98 |
98 void MemoryPressureController::SendPressureNotification( | 99 void MemoryPressureControllerImpl::SendPressureNotification( |
99 const BrowserChildProcessHost* child_process_host, | 100 const BrowserChildProcessHost* child_process_host, |
100 base::MemoryPressureListener::MemoryPressureLevel level) { | 101 base::MemoryPressureListener::MemoryPressureLevel level) { |
101 SendPressureNotificationImpl(child_process_host, level); | 102 SendPressureNotificationImpl(child_process_host, level); |
102 } | 103 } |
103 | 104 |
104 void MemoryPressureController::SendPressureNotification( | 105 void MemoryPressureControllerImpl::SendPressureNotification( |
105 const RenderProcessHost* render_process_host, | 106 const RenderProcessHost* render_process_host, |
106 base::MemoryPressureListener::MemoryPressureLevel level) { | 107 base::MemoryPressureListener::MemoryPressureLevel level) { |
107 SendPressureNotificationImpl(render_process_host, level); | 108 SendPressureNotificationImpl(render_process_host, level); |
108 } | 109 } |
109 | 110 |
110 void MemoryPressureController::SendPressureNotificationImpl( | 111 void MemoryPressureControllerImpl::SendPressureNotificationImpl( |
111 const void* child_process_host, | 112 const void* child_process_host, |
112 base::MemoryPressureListener::MemoryPressureLevel level) { | 113 base::MemoryPressureListener::MemoryPressureLevel level) { |
113 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { | 114 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { |
114 // Note that passing base::Unretained(this) is safe here because the | 115 // Note that passing base::Unretained(this) is safe here because the |
115 // controller is a leaky singleton. It's also safe to pass an untyped | 116 // controller is a leaky singleton. It's also safe to pass an untyped |
116 // child process pointer as the address is only used as a key for lookup in | 117 // child process pointer as the address is only used as a key for lookup in |
117 // a map; at no point is it dereferenced. | 118 // a map; at no point is it dereferenced. |
118 BrowserThread::PostTask( | 119 BrowserThread::PostTask( |
119 BrowserThread::IO, FROM_HERE, | 120 BrowserThread::IO, FROM_HERE, |
120 base::Bind(&MemoryPressureController::SendPressureNotificationImpl, | 121 base::Bind(&MemoryPressureControllerImpl::SendPressureNotificationImpl, |
121 base::Unretained(this), child_process_host, level)); | 122 base::Unretained(this), child_process_host, level)); |
122 return; | 123 return; |
123 } | 124 } |
124 | 125 |
125 if (base::MemoryPressureListener::AreNotificationsSuppressed()) | 126 if (base::MemoryPressureListener::AreNotificationsSuppressed()) |
126 return; | 127 return; |
127 | 128 |
128 // Find the appropriate message filter and dispatch the message. | 129 // Find the appropriate message filter and dispatch the message. |
129 auto it = memory_message_filters_.find(child_process_host); | 130 auto it = memory_message_filters_.find(child_process_host); |
130 if (it != memory_message_filters_.end()) | 131 if (it != memory_message_filters_.end()) |
131 it->second->SendPressureNotification(level); | 132 it->second->SendPressureNotification(level); |
132 } | 133 } |
133 | 134 |
134 } // namespace content | 135 } // namespace content |
OLD | NEW |