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