| 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 |