| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 "chrome/browser/worker_host/worker_service.h" | 5 #include "chrome/browser/worker_host/worker_service.h" |
| 6 | 6 |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/singleton.h" | 8 #include "base/singleton.h" |
| 9 #include "base/sys_info.h" | 9 #include "base/sys_info.h" |
| 10 #include "base/thread.h" | 10 #include "base/thread.h" |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 255 instance->AddSender(sender, sender_route_id); | 255 instance->AddSender(sender, sender_route_id); |
| 256 | 256 |
| 257 // Add the passed sender/document_id to the worker instance. | 257 // Add the passed sender/document_id to the worker instance. |
| 258 instance->worker_document_set()->Add( | 258 instance->worker_document_set()->Add( |
| 259 sender, document_id, renderer_id, render_view_route_id); | 259 sender, document_id, renderer_id, render_view_route_id); |
| 260 return found_instance; | 260 return found_instance; |
| 261 } | 261 } |
| 262 | 262 |
| 263 void WorkerService::DocumentDetached(IPC::Message::Sender* sender, | 263 void WorkerService::DocumentDetached(IPC::Message::Sender* sender, |
| 264 unsigned long long document_id) { | 264 unsigned long long document_id) { |
| 265 for (ChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS); | 265 for (BrowserChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS); |
| 266 !iter.Done(); ++iter) { | 266 !iter.Done(); ++iter) { |
| 267 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); | 267 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); |
| 268 worker->DocumentDetached(sender, document_id); | 268 worker->DocumentDetached(sender, document_id); |
| 269 } | 269 } |
| 270 | 270 |
| 271 // Remove any queued shared workers for this document. | 271 // Remove any queued shared workers for this document. |
| 272 for (WorkerProcessHost::Instances::iterator iter = queued_workers_.begin(); | 272 for (WorkerProcessHost::Instances::iterator iter = queued_workers_.begin(); |
| 273 iter != queued_workers_.end();) { | 273 iter != queued_workers_.end();) { |
| 274 if (iter->shared()) { | 274 if (iter->shared()) { |
| 275 iter->worker_document_set()->Remove(sender, document_id); | 275 iter->worker_document_set()->Remove(sender, document_id); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 302 if (i->HasSender(sender, sender_route_id)) { | 302 if (i->HasSender(sender, sender_route_id)) { |
| 303 DCHECK(!i->shared()); | 303 DCHECK(!i->shared()); |
| 304 queued_workers_.erase(i); | 304 queued_workers_.erase(i); |
| 305 return; | 305 return; |
| 306 } | 306 } |
| 307 } | 307 } |
| 308 | 308 |
| 309 // There could be a race condition where the WebWorkerProxy told us to cancel | 309 // There could be a race condition where the WebWorkerProxy told us to cancel |
| 310 // the worker right as we sent it a message say it's been created. Look at | 310 // the worker right as we sent it a message say it's been created. Look at |
| 311 // the running workers. | 311 // the running workers. |
| 312 for (ChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS); | 312 for (BrowserChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS); |
| 313 !iter.Done(); ++iter) { | 313 !iter.Done(); ++iter) { |
| 314 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); | 314 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); |
| 315 for (WorkerProcessHost::Instances::const_iterator instance = | 315 for (WorkerProcessHost::Instances::const_iterator instance = |
| 316 worker->instances().begin(); | 316 worker->instances().begin(); |
| 317 instance != worker->instances().end(); ++instance) { | 317 instance != worker->instances().end(); ++instance) { |
| 318 if (instance->HasSender(sender, sender_route_id)) { | 318 if (instance->HasSender(sender, sender_route_id)) { |
| 319 // Fake a worker destroyed message so that WorkerProcessHost cleans up | 319 // Fake a worker destroyed message so that WorkerProcessHost cleans up |
| 320 // properly. | 320 // properly. |
| 321 WorkerHostMsg_WorkerContextDestroyed msg(sender_route_id); | 321 WorkerHostMsg_WorkerContextDestroyed msg(sender_route_id); |
| 322 ForwardMessage(msg, sender); | 322 ForwardMessage(msg, sender); |
| 323 return; | 323 return; |
| 324 } | 324 } |
| 325 } | 325 } |
| 326 } | 326 } |
| 327 | 327 |
| 328 DCHECK(false) << "Couldn't find worker to cancel"; | 328 DCHECK(false) << "Couldn't find worker to cancel"; |
| 329 } | 329 } |
| 330 | 330 |
| 331 void WorkerService::ForwardMessage(const IPC::Message& message, | 331 void WorkerService::ForwardMessage(const IPC::Message& message, |
| 332 IPC::Message::Sender* sender) { | 332 IPC::Message::Sender* sender) { |
| 333 for (ChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS); | 333 for (BrowserChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS); |
| 334 !iter.Done(); ++iter) { | 334 !iter.Done(); ++iter) { |
| 335 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); | 335 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); |
| 336 if (worker->FilterMessage(message, sender)) | 336 if (worker->FilterMessage(message, sender)) |
| 337 return; | 337 return; |
| 338 } | 338 } |
| 339 | 339 |
| 340 // TODO(jabdelmalek): tell sender that callee is gone | 340 // TODO(jabdelmalek): tell sender that callee is gone |
| 341 } | 341 } |
| 342 | 342 |
| 343 WorkerProcessHost* WorkerService::GetProcessForDomain(const GURL& url) { | 343 WorkerProcessHost* WorkerService::GetProcessForDomain(const GURL& url) { |
| 344 int num_processes = 0; | 344 int num_processes = 0; |
| 345 std::string domain = | 345 std::string domain = |
| 346 net::RegistryControlledDomainService::GetDomainAndRegistry(url); | 346 net::RegistryControlledDomainService::GetDomainAndRegistry(url); |
| 347 for (ChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS); | 347 for (BrowserChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS); |
| 348 !iter.Done(); ++iter) { | 348 !iter.Done(); ++iter) { |
| 349 num_processes++; | 349 num_processes++; |
| 350 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); | 350 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); |
| 351 for (WorkerProcessHost::Instances::const_iterator instance = | 351 for (WorkerProcessHost::Instances::const_iterator instance = |
| 352 worker->instances().begin(); | 352 worker->instances().begin(); |
| 353 instance != worker->instances().end(); ++instance) { | 353 instance != worker->instances().end(); ++instance) { |
| 354 if (net::RegistryControlledDomainService::GetDomainAndRegistry( | 354 if (net::RegistryControlledDomainService::GetDomainAndRegistry( |
| 355 instance->url()) == domain) { | 355 instance->url()) == domain) { |
| 356 return worker; | 356 return worker; |
| 357 } | 357 } |
| 358 } | 358 } |
| 359 } | 359 } |
| 360 | 360 |
| 361 if (num_processes >= kMaxWorkerProcessesWhenSharing) | 361 if (num_processes >= kMaxWorkerProcessesWhenSharing) |
| 362 return GetLeastLoadedWorker(); | 362 return GetLeastLoadedWorker(); |
| 363 | 363 |
| 364 return NULL; | 364 return NULL; |
| 365 } | 365 } |
| 366 | 366 |
| 367 WorkerProcessHost* WorkerService::GetProcessToFillUpCores() { | 367 WorkerProcessHost* WorkerService::GetProcessToFillUpCores() { |
| 368 int num_processes = 0; | 368 int num_processes = 0; |
| 369 ChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS); | 369 BrowserChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS); |
| 370 for (; !iter.Done(); ++iter) | 370 for (; !iter.Done(); ++iter) |
| 371 num_processes++; | 371 num_processes++; |
| 372 | 372 |
| 373 if (num_processes >= base::SysInfo::NumberOfProcessors()) | 373 if (num_processes >= base::SysInfo::NumberOfProcessors()) |
| 374 return GetLeastLoadedWorker(); | 374 return GetLeastLoadedWorker(); |
| 375 | 375 |
| 376 return NULL; | 376 return NULL; |
| 377 } | 377 } |
| 378 | 378 |
| 379 WorkerProcessHost* WorkerService::GetLeastLoadedWorker() { | 379 WorkerProcessHost* WorkerService::GetLeastLoadedWorker() { |
| 380 WorkerProcessHost* smallest = NULL; | 380 WorkerProcessHost* smallest = NULL; |
| 381 for (ChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS); | 381 for (BrowserChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS); |
| 382 !iter.Done(); ++iter) { | 382 !iter.Done(); ++iter) { |
| 383 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); | 383 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); |
| 384 if (!smallest || worker->instances().size() < smallest->instances().size()) | 384 if (!smallest || worker->instances().size() < smallest->instances().size()) |
| 385 smallest = worker; | 385 smallest = worker; |
| 386 } | 386 } |
| 387 | 387 |
| 388 return smallest; | 388 return smallest; |
| 389 } | 389 } |
| 390 | 390 |
| 391 bool WorkerService::CanCreateWorkerProcess( | 391 bool WorkerService::CanCreateWorkerProcess( |
| (...skipping 20 matching lines...) Expand all Loading... |
| 412 // instance. | 412 // instance. |
| 413 return false; | 413 return false; |
| 414 } | 414 } |
| 415 | 415 |
| 416 bool WorkerService::TabCanCreateWorkerProcess(int renderer_id, | 416 bool WorkerService::TabCanCreateWorkerProcess(int renderer_id, |
| 417 int render_view_route_id, | 417 int render_view_route_id, |
| 418 bool* hit_total_worker_limit) { | 418 bool* hit_total_worker_limit) { |
| 419 int total_workers = 0; | 419 int total_workers = 0; |
| 420 int workers_per_tab = 0; | 420 int workers_per_tab = 0; |
| 421 *hit_total_worker_limit = false; | 421 *hit_total_worker_limit = false; |
| 422 for (ChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS); | 422 for (BrowserChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS); |
| 423 !iter.Done(); ++iter) { | 423 !iter.Done(); ++iter) { |
| 424 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); | 424 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); |
| 425 for (WorkerProcessHost::Instances::const_iterator cur_instance = | 425 for (WorkerProcessHost::Instances::const_iterator cur_instance = |
| 426 worker->instances().begin(); | 426 worker->instances().begin(); |
| 427 cur_instance != worker->instances().end(); ++cur_instance) { | 427 cur_instance != worker->instances().end(); ++cur_instance) { |
| 428 total_workers++; | 428 total_workers++; |
| 429 if (total_workers >= kMaxWorkersWhenSeparate) { | 429 if (total_workers >= kMaxWorkersWhenSeparate) { |
| 430 *hit_total_worker_limit = true; | 430 *hit_total_worker_limit = true; |
| 431 return false; | 431 return false; |
| 432 } | 432 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 450 } else if (type.value == NotificationType::WORKER_PROCESS_HOST_SHUTDOWN) { | 450 } else if (type.value == NotificationType::WORKER_PROCESS_HOST_SHUTDOWN) { |
| 451 WorkerProcessHost* sender = Source<WorkerProcessHost>(source).ptr(); | 451 WorkerProcessHost* sender = Source<WorkerProcessHost>(source).ptr(); |
| 452 SenderShutdown(sender); | 452 SenderShutdown(sender); |
| 453 WorkerProcessDestroyed(sender); | 453 WorkerProcessDestroyed(sender); |
| 454 } else { | 454 } else { |
| 455 NOTREACHED(); | 455 NOTREACHED(); |
| 456 } | 456 } |
| 457 } | 457 } |
| 458 | 458 |
| 459 void WorkerService::SenderShutdown(IPC::Message::Sender* sender) { | 459 void WorkerService::SenderShutdown(IPC::Message::Sender* sender) { |
| 460 for (ChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS); | 460 for (BrowserChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS); |
| 461 !iter.Done(); ++iter) { | 461 !iter.Done(); ++iter) { |
| 462 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); | 462 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); |
| 463 worker->SenderShutdown(sender); | 463 worker->SenderShutdown(sender); |
| 464 } | 464 } |
| 465 | 465 |
| 466 // See if that render process had any queued workers. | 466 // See if that render process had any queued workers. |
| 467 for (WorkerProcessHost::Instances::iterator i = queued_workers_.begin(); | 467 for (WorkerProcessHost::Instances::iterator i = queued_workers_.begin(); |
| 468 i != queued_workers_.end();) { | 468 i != queued_workers_.end();) { |
| 469 i->RemoveSenders(sender); | 469 i->RemoveSenders(sender); |
| 470 if (i->NumSenders() == 0) { | 470 if (i->NumSenders() == 0) { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 505 // rare in practice so the list will be small. | 505 // rare in practice so the list will be small. |
| 506 i = queued_workers_.begin(); | 506 i = queued_workers_.begin(); |
| 507 } else { | 507 } else { |
| 508 ++i; | 508 ++i; |
| 509 } | 509 } |
| 510 } | 510 } |
| 511 } | 511 } |
| 512 | 512 |
| 513 const WorkerProcessHost::WorkerInstance* WorkerService::FindWorkerInstance( | 513 const WorkerProcessHost::WorkerInstance* WorkerService::FindWorkerInstance( |
| 514 int worker_process_id) { | 514 int worker_process_id) { |
| 515 for (ChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS); | 515 for (BrowserChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS); |
| 516 !iter.Done(); ++iter) { | 516 !iter.Done(); ++iter) { |
| 517 if (iter->id() != worker_process_id) | 517 if (iter->id() != worker_process_id) |
| 518 continue; | 518 continue; |
| 519 | 519 |
| 520 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); | 520 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); |
| 521 WorkerProcessHost::Instances::const_iterator instance = | 521 WorkerProcessHost::Instances::const_iterator instance = |
| 522 worker->instances().begin(); | 522 worker->instances().begin(); |
| 523 return instance == worker->instances().end() ? NULL : &*instance; | 523 return instance == worker->instances().end() ? NULL : &*instance; |
| 524 } | 524 } |
| 525 return NULL; | 525 return NULL; |
| 526 } | 526 } |
| 527 | 527 |
| 528 WorkerProcessHost::WorkerInstance* | 528 WorkerProcessHost::WorkerInstance* |
| 529 WorkerService::FindSharedWorkerInstance(const GURL& url, const string16& name, | 529 WorkerService::FindSharedWorkerInstance(const GURL& url, const string16& name, |
| 530 bool off_the_record) { | 530 bool off_the_record) { |
| 531 for (ChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS); | 531 for (BrowserChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS); |
| 532 !iter.Done(); ++iter) { | 532 !iter.Done(); ++iter) { |
| 533 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); | 533 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); |
| 534 for (WorkerProcessHost::Instances::iterator instance_iter = | 534 for (WorkerProcessHost::Instances::iterator instance_iter = |
| 535 worker->mutable_instances().begin(); | 535 worker->mutable_instances().begin(); |
| 536 instance_iter != worker->mutable_instances().end(); | 536 instance_iter != worker->mutable_instances().end(); |
| 537 ++instance_iter) { | 537 ++instance_iter) { |
| 538 if (instance_iter->Matches(url, name, off_the_record)) | 538 if (instance_iter->Matches(url, name, off_the_record)) |
| 539 return &(*instance_iter); | 539 return &(*instance_iter); |
| 540 } | 540 } |
| 541 } | 541 } |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 582 FindPendingInstance(url, name, off_the_record); | 582 FindPendingInstance(url, name, off_the_record); |
| 583 if (instance) | 583 if (instance) |
| 584 return instance; | 584 return instance; |
| 585 | 585 |
| 586 // No existing pending worker - create a new one. | 586 // No existing pending worker - create a new one. |
| 587 WorkerProcessHost::WorkerInstance pending( | 587 WorkerProcessHost::WorkerInstance pending( |
| 588 url, true, off_the_record, name, MSG_ROUTING_NONE, 0, 0, 0, NULL); | 588 url, true, off_the_record, name, MSG_ROUTING_NONE, 0, 0, 0, NULL); |
| 589 pending_shared_workers_.push_back(pending); | 589 pending_shared_workers_.push_back(pending); |
| 590 return &pending_shared_workers_.back(); | 590 return &pending_shared_workers_.back(); |
| 591 } | 591 } |
| OLD | NEW |