| Index: content/browser/service_worker/service_worker_process_manager.cc
|
| diff --git a/content/browser/service_worker/service_worker_process_manager.cc b/content/browser/service_worker/service_worker_process_manager.cc
|
| index ab6012ad97d3e74a38fbd90ad27c68eabdcd8d3e..16e585b9c717939f8d7626e10b7a3253142bd2d6 100644
|
| --- a/content/browser/service_worker/service_worker_process_manager.cc
|
| +++ b/content/browser/service_worker/service_worker_process_manager.cc
|
| @@ -12,6 +12,18 @@
|
|
|
| namespace content {
|
|
|
| +namespace {
|
| +
|
| +// Functor to sort by the .second element of a struct.
|
| +struct SecondGreater {
|
| + template <typename Value>
|
| + bool operator()(const Value& lhs, const Value& rhs) {
|
| + return lhs.second > rhs.second;
|
| + }
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| static bool IncrementWorkerRefCountByPid(int process_id) {
|
| RenderProcessHost* rph = RenderProcessHost::FromID(process_id);
|
| if (!rph || rph->FastShutdownStarted())
|
| @@ -61,9 +73,66 @@ void ServiceWorkerProcessManager::Shutdown() {
|
| instance_info_.clear();
|
| }
|
|
|
| +void ServiceWorkerProcessManager::AddProcessReferenceToPattern(
|
| + const GURL& pattern, int process_id) {
|
| + if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
|
| + BrowserThread::PostTask(
|
| + BrowserThread::UI,
|
| + FROM_HERE,
|
| + base::Bind(&ServiceWorkerProcessManager::AddProcessReferenceToPattern,
|
| + weak_this_,
|
| + pattern,
|
| + process_id));
|
| + return;
|
| + }
|
| +
|
| + ProcessRefMap& process_refs = pattern_processes_[pattern];
|
| + ++process_refs[process_id];
|
| +}
|
| +
|
| +void ServiceWorkerProcessManager::RemoveProcessReferenceFromPattern(
|
| + const GURL& pattern, int process_id) {
|
| + if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
|
| + BrowserThread::PostTask(
|
| + BrowserThread::UI,
|
| + FROM_HERE,
|
| + base::Bind(
|
| + &ServiceWorkerProcessManager::RemoveProcessReferenceFromPattern,
|
| + weak_this_,
|
| + pattern,
|
| + process_id));
|
| + return;
|
| + }
|
| +
|
| + PatternProcessRefMap::iterator it = pattern_processes_.find(pattern);
|
| + if (it == pattern_processes_.end()) {
|
| + NOTREACHED() << "process refrences not found for pattern: " << pattern;
|
| + return;
|
| + }
|
| + ProcessRefMap& process_refs = it->second;
|
| + ProcessRefMap::iterator found = process_refs.find(process_id);
|
| + if (found == process_refs.end()) {
|
| + NOTREACHED() << "Releasing unknown process ref " << process_id;
|
| + return;
|
| + }
|
| + if (--found->second == 0) {
|
| + process_refs.erase(found);
|
| + if (process_refs.empty())
|
| + pattern_processes_.erase(it);
|
| + }
|
| +}
|
| +
|
| +bool ServiceWorkerProcessManager::PatternHasProcessToRun(
|
| + const GURL& pattern) const {
|
| + PatternProcessRefMap::const_iterator it = pattern_processes_.find(pattern);
|
| + if (it == pattern_processes_.end())
|
| + return false;
|
| + return !it->second.empty();
|
| +}
|
| +
|
| void ServiceWorkerProcessManager::AllocateWorkerProcess(
|
| int embedded_worker_id,
|
| - const std::vector<int>& process_ids,
|
| + const GURL& pattern,
|
| const GURL& script_url,
|
| const base::Callback<void(ServiceWorkerStatusCode, int process_id)>&
|
| callback) {
|
| @@ -74,7 +143,7 @@ void ServiceWorkerProcessManager::AllocateWorkerProcess(
|
| base::Bind(&ServiceWorkerProcessManager::AllocateWorkerProcess,
|
| weak_this_,
|
| embedded_worker_id,
|
| - process_ids,
|
| + pattern,
|
| script_url,
|
| callback));
|
| return;
|
| @@ -93,17 +162,18 @@ void ServiceWorkerProcessManager::AllocateWorkerProcess(
|
| DCHECK(!ContainsKey(instance_info_, embedded_worker_id))
|
| << embedded_worker_id << " already has a process allocated";
|
|
|
| - for (std::vector<int>::const_iterator it = process_ids.begin();
|
| - it != process_ids.end();
|
| + std::vector<int> sorted_candidates = SortProcessesForPattern(pattern);
|
| + for (std::vector<int>::const_iterator it = sorted_candidates.begin();
|
| + it != sorted_candidates.end();
|
| ++it) {
|
| - if (IncrementWorkerRefCountByPid(*it)) {
|
| - instance_info_.insert(
|
| - std::make_pair(embedded_worker_id, ProcessInfo(*it)));
|
| - BrowserThread::PostTask(BrowserThread::IO,
|
| - FROM_HERE,
|
| - base::Bind(callback, SERVICE_WORKER_OK, *it));
|
| - return;
|
| - }
|
| + if (!IncrementWorkerRefCountByPid(*it))
|
| + continue;
|
| + instance_info_.insert(
|
| + std::make_pair(embedded_worker_id, ProcessInfo(*it)));
|
| + BrowserThread::PostTask(BrowserThread::IO,
|
| + FROM_HERE,
|
| + base::Bind(callback, SERVICE_WORKER_OK, *it));
|
| + return;
|
| }
|
|
|
| if (!browser_context_) {
|
| @@ -179,6 +249,22 @@ void ServiceWorkerProcessManager::ReleaseWorkerProcess(int embedded_worker_id) {
|
| instance_info_.erase(info);
|
| }
|
|
|
| +std::vector<int> ServiceWorkerProcessManager::SortProcessesForPattern(
|
| + const GURL& pattern) const {
|
| + PatternProcessRefMap::const_iterator it = pattern_processes_.find(pattern);
|
| + if (it == pattern_processes_.end())
|
| + return std::vector<int>();
|
| +
|
| + std::vector<std::pair<int, int> > counted(
|
| + it->second.begin(), it->second.end());
|
| + std::sort(counted.begin(), counted.end(), SecondGreater());
|
| +
|
| + std::vector<int> result(counted.size());
|
| + for (size_t i = 0; i < counted.size(); ++i)
|
| + result[i] = counted[i].first;
|
| + return result;
|
| +}
|
| +
|
| } // namespace content
|
|
|
| namespace base {
|
|
|