| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/service_worker/service_worker_process_manager.h" | 5 #include "content/browser/service_worker/service_worker_process_manager.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <utility> | 10 #include <utility> |
| 11 | 11 |
| 12 #include "content/browser/renderer_host/render_process_host_impl.h" | 12 #include "content/browser/renderer_host/render_process_host_impl.h" |
| 13 #include "content/browser/service_worker/service_worker_context_wrapper.h" | 13 #include "content/browser/service_worker/service_worker_context_wrapper.h" |
| 14 #include "content/common/service_worker/embedded_worker_settings.h" |
| 14 #include "content/public/browser/browser_thread.h" | 15 #include "content/public/browser/browser_thread.h" |
| 16 #include "content/public/browser/content_browser_client.h" |
| 15 #include "content/public/browser/site_instance.h" | 17 #include "content/public/browser/site_instance.h" |
| 16 #include "content/public/common/child_process_host.h" | 18 #include "content/public/common/child_process_host.h" |
| 19 #include "content/public/common/content_client.h" |
| 17 #include "url/gurl.h" | 20 #include "url/gurl.h" |
| 18 | 21 |
| 19 namespace content { | 22 namespace content { |
| 20 | 23 |
| 21 namespace { | 24 namespace { |
| 22 | 25 |
| 23 // Functor to sort by the .second element of a struct. | 26 // Functor to sort by the .second element of a struct. |
| 24 struct SecondGreater { | 27 struct SecondGreater { |
| 25 template <typename Value> | 28 template <typename Value> |
| 26 bool operator()(const Value& lhs, const Value& rhs) { | 29 bool operator()(const Value& lhs, const Value& rhs) { |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 132 return !it->second.empty(); | 135 return !it->second.empty(); |
| 133 } | 136 } |
| 134 | 137 |
| 135 void ServiceWorkerProcessManager::AllocateWorkerProcess( | 138 void ServiceWorkerProcessManager::AllocateWorkerProcess( |
| 136 int embedded_worker_id, | 139 int embedded_worker_id, |
| 137 const GURL& pattern, | 140 const GURL& pattern, |
| 138 const GURL& script_url, | 141 const GURL& script_url, |
| 139 bool can_use_existing_process, | 142 bool can_use_existing_process, |
| 140 const base::Callback<void(ServiceWorkerStatusCode, | 143 const base::Callback<void(ServiceWorkerStatusCode, |
| 141 int process_id, | 144 int process_id, |
| 142 bool is_new_process)>& callback) { | 145 bool is_new_process, |
| 146 const EmbeddedWorkerSettings&)>& callback) { |
| 143 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { | 147 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { |
| 144 BrowserThread::PostTask( | 148 BrowserThread::PostTask( |
| 145 BrowserThread::UI, FROM_HERE, | 149 BrowserThread::UI, FROM_HERE, |
| 146 base::Bind(&ServiceWorkerProcessManager::AllocateWorkerProcess, | 150 base::Bind(&ServiceWorkerProcessManager::AllocateWorkerProcess, |
| 147 weak_this_, embedded_worker_id, pattern, script_url, | 151 weak_this_, embedded_worker_id, pattern, script_url, |
| 148 can_use_existing_process, callback)); | 152 can_use_existing_process, callback)); |
| 149 return; | 153 return; |
| 150 } | 154 } |
| 151 | 155 |
| 156 // This |EmbeddedWorkerSettings| only populates |data_saver_enabled|, |
| 157 // but in general, this function will populate settings from prefs, while |
| 158 // the caller will be responsible for populating settings from other sources, |
| 159 // such as command line switches. |
| 160 EmbeddedWorkerSettings settings; |
| 161 settings.data_saver_enabled = |
| 162 GetContentClient()->browser()->IsDataSaverEnabled(browser_context_); |
| 163 |
| 152 if (process_id_for_test_ != ChildProcessHost::kInvalidUniqueID) { | 164 if (process_id_for_test_ != ChildProcessHost::kInvalidUniqueID) { |
| 153 // Let tests specify the returned process ID. Note: We may need to be able | 165 // Let tests specify the returned process ID. Note: We may need to be able |
| 154 // to specify the error code too. | 166 // to specify the error code too. |
| 155 int result = can_use_existing_process ? process_id_for_test_ | 167 int result = can_use_existing_process ? process_id_for_test_ |
| 156 : new_process_id_for_test_; | 168 : new_process_id_for_test_; |
| 157 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | 169 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
| 158 base::Bind(callback, SERVICE_WORKER_OK, result, | 170 base::Bind(callback, SERVICE_WORKER_OK, result, |
| 159 false /* is_new_process */)); | 171 false /* is_new_process */, settings)); |
| 160 return; | 172 return; |
| 161 } | 173 } |
| 162 | 174 |
| 163 if (IsShutdown()) { | 175 if (IsShutdown()) { |
| 164 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | 176 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
| 165 base::Bind(callback, SERVICE_WORKER_ERROR_ABORT, | 177 base::Bind(callback, SERVICE_WORKER_ERROR_ABORT, |
| 166 ChildProcessHost::kInvalidUniqueID, | 178 ChildProcessHost::kInvalidUniqueID, |
| 167 false /* is_new_process */)); | 179 false /* is_new_process */, settings)); |
| 168 return; | 180 return; |
| 169 } | 181 } |
| 170 | 182 |
| 171 // TODO(nhiroki): Make sure the instance info is not mixed up. | 183 // TODO(nhiroki): Make sure the instance info is not mixed up. |
| 172 // (http://crbug.com/568915) | 184 // (http://crbug.com/568915) |
| 173 CHECK(!ContainsKey(instance_info_, embedded_worker_id)) | 185 CHECK(!ContainsKey(instance_info_, embedded_worker_id)) |
| 174 << embedded_worker_id << " already has a process allocated"; | 186 << embedded_worker_id << " already has a process allocated"; |
| 175 | 187 |
| 176 if (can_use_existing_process) { | 188 if (can_use_existing_process) { |
| 177 int process_id = FindAvailableProcess(pattern); | 189 int process_id = FindAvailableProcess(pattern); |
| 178 if (process_id != ChildProcessHost::kInvalidUniqueID) { | 190 if (process_id != ChildProcessHost::kInvalidUniqueID) { |
| 179 RenderProcessHost::FromID(process_id)->IncrementWorkerRefCount(); | 191 RenderProcessHost::FromID(process_id)->IncrementWorkerRefCount(); |
| 180 instance_info_.insert( | 192 instance_info_.insert( |
| 181 std::make_pair(embedded_worker_id, ProcessInfo(process_id))); | 193 std::make_pair(embedded_worker_id, ProcessInfo(process_id))); |
| 182 BrowserThread::PostTask( | 194 BrowserThread::PostTask( |
| 183 BrowserThread::IO, FROM_HERE, | 195 BrowserThread::IO, FROM_HERE, |
| 184 base::Bind(callback, SERVICE_WORKER_OK, process_id, | 196 base::Bind(callback, SERVICE_WORKER_OK, process_id, |
| 185 false /* is_new_process */)); | 197 false /* is_new_process */, settings)); |
| 186 return; | 198 return; |
| 187 } | 199 } |
| 188 } | 200 } |
| 189 | 201 |
| 190 // No existing processes available; start a new one. | 202 // No existing processes available; start a new one. |
| 191 scoped_refptr<SiteInstance> site_instance = | 203 scoped_refptr<SiteInstance> site_instance = |
| 192 SiteInstance::CreateForURL(browser_context_, script_url); | 204 SiteInstance::CreateForURL(browser_context_, script_url); |
| 193 RenderProcessHost* rph = site_instance->GetProcess(); | 205 RenderProcessHost* rph = site_instance->GetProcess(); |
| 194 | 206 |
| 195 // This Init() call posts a task to the IO thread that adds the RPH's | 207 // This Init() call posts a task to the IO thread that adds the RPH's |
| 196 // ServiceWorkerDispatcherHost to the | 208 // ServiceWorkerDispatcherHost to the |
| 197 // EmbeddedWorkerRegistry::process_sender_map_. | 209 // EmbeddedWorkerRegistry::process_sender_map_. |
| 198 if (!rph->Init()) { | 210 if (!rph->Init()) { |
| 199 LOG(ERROR) << "Couldn't start a new process!"; | 211 LOG(ERROR) << "Couldn't start a new process!"; |
| 200 BrowserThread::PostTask( | 212 BrowserThread::PostTask( |
| 201 BrowserThread::IO, FROM_HERE, | 213 BrowserThread::IO, FROM_HERE, |
| 202 base::Bind(callback, SERVICE_WORKER_ERROR_PROCESS_NOT_FOUND, | 214 base::Bind(callback, SERVICE_WORKER_ERROR_PROCESS_NOT_FOUND, |
| 203 ChildProcessHost::kInvalidUniqueID, | 215 ChildProcessHost::kInvalidUniqueID, |
| 204 false /* is_new_process */)); | 216 false /* is_new_process */, settings)); |
| 205 return; | 217 return; |
| 206 } | 218 } |
| 207 | 219 |
| 208 instance_info_.insert( | 220 instance_info_.insert( |
| 209 std::make_pair(embedded_worker_id, ProcessInfo(site_instance))); | 221 std::make_pair(embedded_worker_id, ProcessInfo(site_instance))); |
| 210 | 222 |
| 211 rph->IncrementWorkerRefCount(); | 223 rph->IncrementWorkerRefCount(); |
| 212 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | 224 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
| 213 base::Bind(callback, SERVICE_WORKER_OK, rph->GetID(), | 225 base::Bind(callback, SERVICE_WORKER_OK, rph->GetID(), |
| 214 true /* is_new_process */)); | 226 true /* is_new_process */, settings)); |
| 215 } | 227 } |
| 216 | 228 |
| 217 void ServiceWorkerProcessManager::ReleaseWorkerProcess(int embedded_worker_id) { | 229 void ServiceWorkerProcessManager::ReleaseWorkerProcess(int embedded_worker_id) { |
| 218 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { | 230 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { |
| 219 BrowserThread::PostTask( | 231 BrowserThread::PostTask( |
| 220 BrowserThread::UI, | 232 BrowserThread::UI, |
| 221 FROM_HERE, | 233 FROM_HERE, |
| 222 base::Bind(&ServiceWorkerProcessManager::ReleaseWorkerProcess, | 234 base::Bind(&ServiceWorkerProcessManager::ReleaseWorkerProcess, |
| 223 weak_this_, | 235 weak_this_, |
| 224 embedded_worker_id)); | 236 embedded_worker_id)); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 311 namespace std { | 323 namespace std { |
| 312 // Destroying ServiceWorkerProcessManagers only on the UI thread allows the | 324 // Destroying ServiceWorkerProcessManagers only on the UI thread allows the |
| 313 // member WeakPtr to safely guard the object's lifetime when used on that | 325 // member WeakPtr to safely guard the object's lifetime when used on that |
| 314 // thread. | 326 // thread. |
| 315 void default_delete<content::ServiceWorkerProcessManager>::operator()( | 327 void default_delete<content::ServiceWorkerProcessManager>::operator()( |
| 316 content::ServiceWorkerProcessManager* ptr) const { | 328 content::ServiceWorkerProcessManager* ptr) const { |
| 317 content::BrowserThread::DeleteSoon( | 329 content::BrowserThread::DeleteSoon( |
| 318 content::BrowserThread::UI, FROM_HERE, ptr); | 330 content::BrowserThread::UI, FROM_HERE, ptr); |
| 319 } | 331 } |
| 320 } // namespace std | 332 } // namespace std |
| OLD | NEW |