| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "components/update_client/update_client.h" | 5 #include "components/update_client/update_client.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <queue> | 8 #include <queue> |
| 9 #include <set> | 9 #include <set> |
| 10 #include <utility> | 10 #include <utility> |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 // pointer to itself. Otherwise, a life time circular dependency between this | 61 // pointer to itself. Otherwise, a life time circular dependency between this |
| 62 // instance and its inner members prevents the destruction of this instance. | 62 // instance and its inner members prevents the destruction of this instance. |
| 63 // Using unretained references is allowed in this case since the life time of | 63 // Using unretained references is allowed in this case since the life time of |
| 64 // the UpdateClient instance exceeds the life time of its inner members, | 64 // the UpdateClient instance exceeds the life time of its inner members, |
| 65 // including any thread objects that might execute callbacks bound to it. | 65 // including any thread objects that might execute callbacks bound to it. |
| 66 UpdateClientImpl::UpdateClientImpl( | 66 UpdateClientImpl::UpdateClientImpl( |
| 67 const scoped_refptr<Configurator>& config, | 67 const scoped_refptr<Configurator>& config, |
| 68 scoped_ptr<PingManager> ping_manager, | 68 scoped_ptr<PingManager> ping_manager, |
| 69 UpdateChecker::Factory update_checker_factory, | 69 UpdateChecker::Factory update_checker_factory, |
| 70 CrxDownloader::Factory crx_downloader_factory) | 70 CrxDownloader::Factory crx_downloader_factory) |
| 71 : config_(config), | 71 : is_stopped_(false), |
| 72 config_(config), |
| 72 ping_manager_(ping_manager.Pass()), | 73 ping_manager_(ping_manager.Pass()), |
| 73 update_engine_( | 74 update_engine_( |
| 74 new UpdateEngine(config, | 75 new UpdateEngine(config, |
| 75 update_checker_factory, | 76 update_checker_factory, |
| 76 crx_downloader_factory, | 77 crx_downloader_factory, |
| 77 ping_manager_.get(), | 78 ping_manager_.get(), |
| 78 base::Bind(&UpdateClientImpl::NotifyObservers, | 79 base::Bind(&UpdateClientImpl::NotifyObservers, |
| 79 base::Unretained(this)))) { | 80 base::Unretained(this)))) {} |
| 80 } | |
| 81 | 81 |
| 82 UpdateClientImpl::~UpdateClientImpl() { | 82 UpdateClientImpl::~UpdateClientImpl() { |
| 83 DCHECK(thread_checker_.CalledOnValidThread()); | 83 DCHECK(thread_checker_.CalledOnValidThread()); |
| 84 | 84 |
| 85 while (!task_queue_.empty()) { | 85 DCHECK(task_queue_.empty()); |
| 86 delete task_queue_.front(); | 86 DCHECK(tasks_.empty()); |
| 87 task_queue_.pop(); | |
| 88 } | |
| 89 | 87 |
| 90 config_ = nullptr; | 88 config_ = nullptr; |
| 91 } | 89 } |
| 92 | 90 |
| 93 void UpdateClientImpl::Install(const std::string& id, | 91 void UpdateClientImpl::Install(const std::string& id, |
| 94 const CrxDataCallback& crx_data_callback, | 92 const CrxDataCallback& crx_data_callback, |
| 95 const CompletionCallback& completion_callback) { | 93 const CompletionCallback& completion_callback) { |
| 96 DCHECK(thread_checker_.CalledOnValidThread()); | 94 DCHECK(thread_checker_.CalledOnValidThread()); |
| 97 | 95 |
| 98 if (IsUpdating(id)) { | 96 if (IsUpdating(id)) { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 143 void UpdateClientImpl::OnTaskComplete( | 141 void UpdateClientImpl::OnTaskComplete( |
| 144 const CompletionCallback& completion_callback, | 142 const CompletionCallback& completion_callback, |
| 145 Task* task, | 143 Task* task, |
| 146 int error) { | 144 int error) { |
| 147 DCHECK(thread_checker_.CalledOnValidThread()); | 145 DCHECK(thread_checker_.CalledOnValidThread()); |
| 148 DCHECK(task); | 146 DCHECK(task); |
| 149 | 147 |
| 150 base::ThreadTaskRunnerHandle::Get()->PostTask( | 148 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 151 FROM_HERE, base::Bind(completion_callback, error)); | 149 FROM_HERE, base::Bind(completion_callback, error)); |
| 152 | 150 |
| 151 // Remove the task from the set of the running tasks. Only tasks handled by |
| 152 // the update engine can be in this data structure. |
| 153 tasks_.erase(task); | 153 tasks_.erase(task); |
| 154 |
| 155 // Delete the completed task. A task can be completed because the update |
| 156 // engine has run it or because it has been canceled but never run. |
| 154 delete task; | 157 delete task; |
| 155 | 158 |
| 159 if (is_stopped_) |
| 160 return; |
| 161 |
| 156 // Pick up a task from the queue if the queue has pending tasks and no other | 162 // Pick up a task from the queue if the queue has pending tasks and no other |
| 157 // task is running. | 163 // task is running. |
| 158 if (tasks_.empty() && !task_queue_.empty()) { | 164 if (tasks_.empty() && !task_queue_.empty()) { |
| 159 RunTask(scoped_ptr<Task>(task_queue_.front()).Pass()); | 165 RunTask(scoped_ptr<Task>(task_queue_.front()).Pass()); |
| 160 task_queue_.pop(); | 166 task_queue_.pop(); |
| 161 } | 167 } |
| 162 } | 168 } |
| 163 | 169 |
| 164 void UpdateClientImpl::AddObserver(Observer* observer) { | 170 void UpdateClientImpl::AddObserver(Observer* observer) { |
| 165 DCHECK(thread_checker_.CalledOnValidThread()); | 171 DCHECK(thread_checker_.CalledOnValidThread()); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 188 for (const auto& task : tasks_) { | 194 for (const auto& task : tasks_) { |
| 189 const auto ids(task->GetIds()); | 195 const auto ids(task->GetIds()); |
| 190 if (std::find(ids.begin(), ids.end(), id) != ids.end()) { | 196 if (std::find(ids.begin(), ids.end(), id) != ids.end()) { |
| 191 return true; | 197 return true; |
| 192 } | 198 } |
| 193 } | 199 } |
| 194 | 200 |
| 195 return false; | 201 return false; |
| 196 } | 202 } |
| 197 | 203 |
| 204 void UpdateClientImpl::Stop() { |
| 205 DCHECK(thread_checker_.CalledOnValidThread()); |
| 206 |
| 207 is_stopped_ = true; |
| 208 |
| 209 // In the current implementation it is sufficient to cancel the pending |
| 210 // tasks only. The tasks that are run by the update engine will stop |
| 211 // making progress naturally, as the main task runner stops running task |
| 212 // actions. Upon the browser shutdown, the resources employed by the active |
| 213 // tasks will leak, as the operating system kills the thread associated with |
| 214 // the update engine task runner. Further refactoring may be needed in this |
| 215 // area, to cancel the running tasks by canceling the current action update. |
| 216 // This behavior would be expected, correct, and result in no resource leaks |
| 217 // in all cases, in shutdown or not. |
| 218 // |
| 219 // Cancel the pending tasks. These tasks are safe to cancel and delete since |
| 220 // they have not picked up by the update engine, and not shared with any |
| 221 // task runner yet. |
| 222 while (!task_queue_.empty()) { |
| 223 const auto task(task_queue_.front()); |
| 224 task_queue_.pop(); |
| 225 task->Cancel(); |
| 226 } |
| 227 } |
| 228 |
| 198 scoped_refptr<UpdateClient> UpdateClientFactory( | 229 scoped_refptr<UpdateClient> UpdateClientFactory( |
| 199 const scoped_refptr<Configurator>& config) { | 230 const scoped_refptr<Configurator>& config) { |
| 200 scoped_ptr<PingManager> ping_manager(new PingManager(*config)); | 231 scoped_ptr<PingManager> ping_manager(new PingManager(*config)); |
| 201 return new UpdateClientImpl(config, ping_manager.Pass(), | 232 return new UpdateClientImpl(config, ping_manager.Pass(), |
| 202 &UpdateChecker::Create, &CrxDownloader::Create); | 233 &UpdateChecker::Create, &CrxDownloader::Create); |
| 203 } | 234 } |
| 204 | 235 |
| 205 } // namespace update_client | 236 } // namespace update_client |
| OLD | NEW |