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

Side by Side Diff: content/browser/service_worker/embedded_worker_instance.cc

Issue 238043002: Teach EmbeddedWorkerInstance to create a process when it needs one. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Handle 2 places where context_ could be NULL. Created 6 years, 7 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/embedded_worker_instance.h" 5 #include "content/browser/service_worker/embedded_worker_instance.h"
6 6
7 #include "content/browser/service_worker/embedded_worker_registry.h" 7 #include "content/browser/service_worker/embedded_worker_registry.h"
8 #include "content/common/service_worker/embedded_worker_messages.h" 8 #include "content/common/service_worker/embedded_worker_messages.h"
9 #include "ipc/ipc_message.h" 9 #include "ipc/ipc_message.h"
10 #include "url/gurl.h" 10 #include "url/gurl.h"
11 11
12 namespace content { 12 namespace content {
13 13
14 namespace {
15 // Functor to sort by the .second element of a struct.
16 struct SecondGreater {
17 template <typename Value>
18 bool operator()(const Value& lhs, const Value& rhs) {
19 return lhs.second > rhs.second;
20 }
21 };
22 } // namespace
23
14 EmbeddedWorkerInstance::~EmbeddedWorkerInstance() { 24 EmbeddedWorkerInstance::~EmbeddedWorkerInstance() {
15 registry_->RemoveWorker(process_id_, embedded_worker_id_); 25 registry_->RemoveWorker(process_id_, embedded_worker_id_);
16 } 26 }
17 27
18 ServiceWorkerStatusCode EmbeddedWorkerInstance::Start( 28 void EmbeddedWorkerInstance::Start(int64 service_worker_version_id,
19 int64 service_worker_version_id, 29 const GURL& scope,
20 const GURL& scope, 30 const GURL& script_url,
21 const GURL& script_url) { 31 const std::vector<int>& possible_process_ids,
32 const StatusCallback& callback) {
22 DCHECK(status_ == STOPPED); 33 DCHECK(status_ == STOPPED);
23 if (!ChooseProcess())
24 return SERVICE_WORKER_ERROR_PROCESS_NOT_FOUND;
25 status_ = STARTING; 34 status_ = STARTING;
26 ServiceWorkerStatusCode status = 35 std::vector<int> ordered_process_ids = SortProcesses(possible_process_ids);
27 registry_->StartWorker(process_id_, 36 registry_->StartWorker(ordered_process_ids,
28 embedded_worker_id_, 37 embedded_worker_id_,
29 service_worker_version_id, 38 service_worker_version_id,
30 scope, 39 scope,
31 script_url); 40 script_url,
32 if (status != SERVICE_WORKER_OK) { 41 callback);
33 status_ = STOPPED;
34 process_id_ = -1;
35 }
36 return status;
37 } 42 }
38 43
39 ServiceWorkerStatusCode EmbeddedWorkerInstance::Stop() { 44 ServiceWorkerStatusCode EmbeddedWorkerInstance::Stop() {
40 DCHECK(status_ == STARTING || status_ == RUNNING); 45 DCHECK(status_ == STARTING || status_ == RUNNING);
41 ServiceWorkerStatusCode status = 46 ServiceWorkerStatusCode status =
42 registry_->StopWorker(process_id_, embedded_worker_id_); 47 registry_->StopWorker(process_id_, embedded_worker_id_);
43 if (status == SERVICE_WORKER_OK) 48 if (status == SERVICE_WORKER_OK)
44 status_ = STOPPING; 49 status_ = STOPPING;
45 return status; 50 return status;
46 } 51 }
(...skipping 26 matching lines...) Expand all
73 EmbeddedWorkerInstance::EmbeddedWorkerInstance( 78 EmbeddedWorkerInstance::EmbeddedWorkerInstance(
74 EmbeddedWorkerRegistry* registry, 79 EmbeddedWorkerRegistry* registry,
75 int embedded_worker_id) 80 int embedded_worker_id)
76 : registry_(registry), 81 : registry_(registry),
77 embedded_worker_id_(embedded_worker_id), 82 embedded_worker_id_(embedded_worker_id),
78 status_(STOPPED), 83 status_(STOPPED),
79 process_id_(-1), 84 process_id_(-1),
80 thread_id_(-1) { 85 thread_id_(-1) {
81 } 86 }
82 87
88 void EmbeddedWorkerInstance::RecordProcessId(int process_id,
89 ServiceWorkerStatusCode status) {
90 DCHECK_EQ(process_id_, -1);
91 if (status == SERVICE_WORKER_OK) {
92 process_id_ = process_id;
93 } else {
94 status_ = STOPPED;
95 }
96 }
97
83 void EmbeddedWorkerInstance::OnStarted(int thread_id) { 98 void EmbeddedWorkerInstance::OnStarted(int thread_id) {
84 // Stop is requested before OnStarted is sent back from the worker. 99 // Stop is requested before OnStarted is sent back from the worker.
85 if (status_ == STOPPING) 100 if (status_ == STOPPING)
86 return; 101 return;
87 DCHECK(status_ == STARTING); 102 DCHECK(status_ == STARTING);
88 status_ = RUNNING; 103 status_ = RUNNING;
89 thread_id_ = thread_id; 104 thread_id_ = thread_id;
90 FOR_EACH_OBSERVER(Listener, listener_list_, OnStarted()); 105 FOR_EACH_OBSERVER(Listener, listener_list_, OnStarted());
91 } 106 }
92 107
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 } 146 }
132 147
133 void EmbeddedWorkerInstance::AddListener(Listener* listener) { 148 void EmbeddedWorkerInstance::AddListener(Listener* listener) {
134 listener_list_.AddObserver(listener); 149 listener_list_.AddObserver(listener);
135 } 150 }
136 151
137 void EmbeddedWorkerInstance::RemoveListener(Listener* listener) { 152 void EmbeddedWorkerInstance::RemoveListener(Listener* listener) {
138 listener_list_.RemoveObserver(listener); 153 listener_list_.RemoveObserver(listener);
139 } 154 }
140 155
141 bool EmbeddedWorkerInstance::ChooseProcess() { 156 std::vector<int> EmbeddedWorkerInstance::SortProcesses(
142 DCHECK_EQ(-1, process_id_); 157 const std::vector<int>& possible_process_ids) const {
143 // Naive implementation; chooses a process which has the biggest number of 158 // Add the |possible_process_ids| to the existing process_refs_ since each one
144 // associated providers (so that hopefully likely live longer). 159 // is likely to take a reference once the SW starts up.
145 ProcessRefMap::iterator max_ref_iter = process_refs_.end(); 160 ProcessRefMap refs_with_new_ids = process_refs_;
146 for (ProcessRefMap::iterator iter = process_refs_.begin(); 161 for (std::vector<int>::const_iterator it = possible_process_ids.begin();
147 iter != process_refs_.end(); ++iter) { 162 it != possible_process_ids.end();
148 if (max_ref_iter == process_refs_.end() || 163 ++it) {
149 max_ref_iter->second < iter->second) 164 refs_with_new_ids[*it]++;
150 max_ref_iter = iter;
151 } 165 }
152 if (max_ref_iter == process_refs_.end()) 166
153 return false; 167 std::vector<std::pair<int, int> > counted(refs_with_new_ids.begin(),
154 process_id_ = max_ref_iter->first; 168 refs_with_new_ids.end());
155 return true; 169 // Sort descending by the reference count.
170 std::sort(counted.begin(), counted.end(), SecondGreater());
171
172 std::vector<int> result(counted.size());
173 for (size_t i = 0; i < counted.size(); ++i)
174 result[i] = counted[i].first;
175 return result;
156 } 176 }
157 177
158 } // namespace content 178 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698