Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(31)

Unified Diff: content/browser/service_worker/service_worker_process_manager.cc

Issue 443593002: ServiceWorker: Move worker candidate process knowledge to ServiceWorkerProcessManager. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: RPH observer DCHECK and browser tests build fix Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 7395e7b7b7768675ed4d9225df4436e6a6ba5917..65e9aba6c710af4413368fd7785409b2f376bb2d 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,117 @@ void ServiceWorkerProcessManager::Shutdown() {
instance_info_.clear();
}
+void ServiceWorkerProcessManager::AddScopePendingProcesses(
+ const GURL& scope, const std::vector<int>& pending_processes) {
kinuko 2014/08/12 15:27:07 Looks like these methods are called only on IO thr
kinuko 2014/08/12 15:42:48 Oops, this comment was irrelevant, please ignore t
+ if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
+ BrowserThread::PostTask(
+ BrowserThread::UI,
+ FROM_HERE,
+ base::Bind(&ServiceWorkerProcessManager::AddScopePendingProcesses,
+ weak_this_,
+ scope,
+ pending_processes));
+ return;
+ }
+
+ ProcessRefMap& process_refs = scope_processes_[scope];
+ for (std::vector<int>::const_iterator it = pending_processes.begin();
+ it != pending_processes.end();
+ ++it) {
+ if (process_refs.find(*it) != process_refs.end())
+ continue;
+ RenderProcessHost* host = RenderProcessHost::FromID(*it);
+ if (!host && *it != process_id_for_test_)
+ continue;
+ if (host) {
+ // FIXME: the pending process maybe contained by multiple scopes, as
Jeffrey Yasskin 2014/08/19 23:42:24 s/maybe/may be/
+ // RPH doesn't have "HasObserver" method, let's remove it first.
Jeffrey Yasskin 2014/08/19 23:42:24 s/method, let's/method. Let's/
xiang 2014/08/29 07:49:39 this method is removed.
+ host->RemoveObserver(this);
+ host->AddObserver(this);
+ }
+ process_refs.insert(std::make_pair(*it, 0));
+ }
+}
+
+void ServiceWorkerProcessManager::AddScopeProcessReference(
+ const GURL& scope, int process_id) {
+ if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
+ BrowserThread::PostTask(
+ BrowserThread::UI,
+ FROM_HERE,
+ base::Bind(&ServiceWorkerProcessManager::AddScopeProcessReference,
+ weak_this_,
+ scope,
+ process_id));
+ return;
+ }
+
+ ProcessRefMap& process_refs = scope_processes_[scope];
+ ProcessRefMap::iterator found = process_refs.find(process_id);
Jeffrey Yasskin 2014/08/19 23:42:24 You can write these 4 lines as: ++process_refs[pr
xiang 2014/08/29 07:49:39 Done.
+ if (found == process_refs.end())
+ found = process_refs.insert(std::make_pair(process_id, 0)).first;
+ ++found->second;
+}
+
+void ServiceWorkerProcessManager::RemoveScopeProcessReference(
+ const GURL& scope, int process_id) {
+ if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
+ BrowserThread::PostTask(
+ BrowserThread::UI,
+ FROM_HERE,
+ base::Bind(&ServiceWorkerProcessManager::RemoveScopeProcessReference,
+ weak_this_,
+ scope,
+ process_id));
+ return;
+ }
+
+ ScopeProcessRefMap::iterator it = scope_processes_.find(scope);
+ if (it == scope_processes_.end()) {
+ NOTREACHED() << "Scope process refrences not found: " << scope;
+ 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) {
Jeffrey Yasskin 2014/08/19 23:42:23 You're not guarding against releasing a pending pr
xiang 2014/08/29 07:49:39 we don't have pending process now.
+ process_refs.erase(found);
+ if (process_refs.empty())
+ scope_processes_.erase(it);
+ }
+}
+
+bool ServiceWorkerProcessManager::ScopeHasProcessToRun(
+ const GURL& scope) const {
+ ScopeProcessRefMap::const_iterator it = scope_processes_.find(scope);
+ if (it == scope_processes_.end())
+ return false;
+ return !it->second.empty();
+}
+
+void ServiceWorkerProcessManager::RenderProcessHostDestroyed(
+ RenderProcessHost* host) {
+ ScopeProcessRefMap::iterator it = scope_processes_.begin();
+ while (it != scope_processes_.end()) {
+ ProcessRefMap& process_refs = it->second;
+ ProcessRefMap::iterator found = process_refs.find(host->GetID());
+ if (found != process_refs.end()) {
+ process_refs.erase(found);
+ if (process_refs.empty()) {
+ scope_processes_.erase(it++);
+ continue;
+ }
+ }
+ ++it;
+ }
+}
+
void ServiceWorkerProcessManager::AllocateWorkerProcess(
int embedded_worker_id,
- const std::vector<int>& process_ids,
+ const GURL& scope,
const GURL& script_url,
const base::Callback<void(ServiceWorkerStatusCode, int process_id)>&
callback) {
@@ -74,7 +194,7 @@ void ServiceWorkerProcessManager::AllocateWorkerProcess(
base::Bind(&ServiceWorkerProcessManager::AllocateWorkerProcess,
weak_this_,
embedded_worker_id,
- process_ids,
+ scope,
script_url,
callback));
return;
@@ -93,10 +213,13 @@ 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();
- ++it) {
- if (IncrementWorkerRefCountByPid(*it)) {
+ std::vector<int> sorted_candidates = SortProcessesForScope(scope);
+ if (!sorted_candidates.empty()) {
Jeffrey Yasskin 2014/08/19 23:42:23 You don't need to check this. If sorted_candidates
xiang 2014/08/29 07:49:39 Done.
+ for (std::vector<int>::const_iterator it = sorted_candidates.begin();
+ it != sorted_candidates.end();
+ ++it) {
+ if (!IncrementWorkerRefCountByPid(*it))
+ continue;
instance_info_.insert(
std::make_pair(embedded_worker_id, ProcessInfo(*it)));
BrowserThread::PostTask(BrowserThread::IO,
@@ -179,6 +302,22 @@ void ServiceWorkerProcessManager::ReleaseWorkerProcess(int embedded_worker_id) {
instance_info_.erase(info);
}
+std::vector<int> ServiceWorkerProcessManager::SortProcessesForScope(
+ const GURL& scope) const {
+ ScopeProcessRefMap::const_iterator it = scope_processes_.find(scope);
+ if (it == scope_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 {

Powered by Google App Engine
This is Rietveld 408576698