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

Side by Side Diff: content/browser/background_fetch/background_fetch_job_controller.cc

Issue 2973233002: [Background Fetch] Cleanup/fix thread safety (Closed)
Patch Set: Remove n.b. from comments Created 3 years, 5 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
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 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/background_fetch/background_fetch_job_controller.h" 5 #include "content/browser/background_fetch/background_fetch_job_controller.h"
6 6
7 #include <string> 7 #include <string>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 30 matching lines...) Expand all
41 class BackgroundFetchJobController::Core : public DownloadItem::Observer { 41 class BackgroundFetchJobController::Core : public DownloadItem::Observer {
42 public: 42 public:
43 Core(const base::WeakPtr<BackgroundFetchJobController>& io_parent, 43 Core(const base::WeakPtr<BackgroundFetchJobController>& io_parent,
44 const BackgroundFetchRegistrationId& registration_id, 44 const BackgroundFetchRegistrationId& registration_id,
45 BrowserContext* browser_context, 45 BrowserContext* browser_context,
46 scoped_refptr<net::URLRequestContextGetter> request_context) 46 scoped_refptr<net::URLRequestContextGetter> request_context)
47 : io_parent_(io_parent), 47 : io_parent_(io_parent),
48 registration_id_(registration_id), 48 registration_id_(registration_id),
49 browser_context_(browser_context), 49 browser_context_(browser_context),
50 request_context_(std::move(request_context)), 50 request_context_(std::move(request_context)),
51 weak_ptr_factory_(this) {} 51 weak_ptr_factory_(this) {
52 // Although the Core lives only on the UI thread, it is constructed on IO.
53 DCHECK_CURRENTLY_ON(BrowserThread::IO);
54 }
52 55
53 ~Core() final { 56 ~Core() final {
57 DCHECK_CURRENTLY_ON(BrowserThread::UI);
54 for (const auto& pair : downloads_) 58 for (const auto& pair : downloads_)
55 pair.first->RemoveObserver(this); 59 pair.first->RemoveObserver(this);
56 } 60 }
57 61
58 // Returns a weak pointer that can be used to talk to |this|. 62 // Returns a weak pointer that can be used to talk to |this|. Must only be
59 base::WeakPtr<Core> GetWeakPtr() { return weak_ptr_factory_.GetWeakPtr(); } 63 // called on the UI thread, unless the Core is guaranteed not to be destroyed
64 // in parallel with this call.
65 base::WeakPtr<Core> GetWeakPtrOnUI() {
66 return weak_ptr_factory_.GetWeakPtr();
67 }
60 68
61 // Starts fetching the |request| with the download manager. 69 // Starts fetching the |request| with the download manager.
62 void StartRequest( 70 void StartRequest(
63 scoped_refptr<BackgroundFetchRequestInfo> request, 71 scoped_refptr<BackgroundFetchRequestInfo> request,
64 const net::NetworkTrafficAnnotationTag& traffic_annotation) { 72 const net::NetworkTrafficAnnotationTag& traffic_annotation) {
65 DCHECK_CURRENTLY_ON(BrowserThread::UI); 73 DCHECK_CURRENTLY_ON(BrowserThread::UI);
66 DCHECK(request_context_); 74 DCHECK(request_context_);
67 DCHECK(request); 75 DCHECK(request);
68 76
69 DownloadManager* download_manager = 77 DownloadManager* download_manager =
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 void OnDownloadUpdated(DownloadItem* download_item) override { 125 void OnDownloadUpdated(DownloadItem* download_item) override {
118 DCHECK_CURRENTLY_ON(BrowserThread::UI); 126 DCHECK_CURRENTLY_ON(BrowserThread::UI);
119 127
120 auto iter = downloads_.find(download_item); 128 auto iter = downloads_.find(download_item);
121 DCHECK(iter != downloads_.end()); 129 DCHECK(iter != downloads_.end());
122 130
123 scoped_refptr<BackgroundFetchRequestInfo> request = iter->second; 131 scoped_refptr<BackgroundFetchRequestInfo> request = iter->second;
124 132
125 switch (download_item->GetState()) { 133 switch (download_item->GetState()) {
126 case DownloadItem::DownloadState::COMPLETE: 134 case DownloadItem::DownloadState::COMPLETE:
127 request->PopulateResponseFromDownloadItem(download_item); 135 request->PopulateResponseFromDownloadItemOnUI(download_item);
136 BrowserThread::PostTask(
137 BrowserThread::IO, FROM_HERE,
138 base::Bind(&BackgroundFetchRequestInfo::SetResponseDataPopulated,
139 request));
128 download_item->RemoveObserver(this); 140 download_item->RemoveObserver(this);
129 141
130 // Inform the host about |host| having completed. 142 // Inform the host about |host| having completed.
131 BrowserThread::PostTask( 143 BrowserThread::PostTask(
132 BrowserThread::IO, FROM_HERE, 144 BrowserThread::IO, FROM_HERE,
133 base::Bind(&BackgroundFetchJobController::DidCompleteRequest, 145 base::Bind(&BackgroundFetchJobController::DidCompleteRequest,
134 io_parent_, std::move(request))); 146 io_parent_, std::move(request)));
135 147
136 // Clear the local state for the |request|, it no longer is our concern. 148 // Clear the local state for the |request|, it no longer is our concern.
137 downloads_.erase(iter); 149 downloads_.erase(iter);
(...skipping 26 matching lines...) Expand all
164 // Called when the download manager has started the given |request|. The 176 // Called when the download manager has started the given |request|. The
165 // |download_item| continues to be owned by the download system. The 177 // |download_item| continues to be owned by the download system. The
166 // |interrupt_reason| will indicate when a request could not be started. 178 // |interrupt_reason| will indicate when a request could not be started.
167 void DidStartRequest(scoped_refptr<BackgroundFetchRequestInfo> request, 179 void DidStartRequest(scoped_refptr<BackgroundFetchRequestInfo> request,
168 DownloadItem* download_item, 180 DownloadItem* download_item,
169 DownloadInterruptReason interrupt_reason) { 181 DownloadInterruptReason interrupt_reason) {
170 DCHECK_CURRENTLY_ON(BrowserThread::UI); 182 DCHECK_CURRENTLY_ON(BrowserThread::UI);
171 DCHECK_EQ(interrupt_reason, DOWNLOAD_INTERRUPT_REASON_NONE); 183 DCHECK_EQ(interrupt_reason, DOWNLOAD_INTERRUPT_REASON_NONE);
172 DCHECK(download_item); 184 DCHECK(download_item);
173 185
174 request->PopulateDownloadState(download_item, interrupt_reason); 186 request->PopulateDownloadStateOnUI(download_item, interrupt_reason);
187 BrowserThread::PostTask(
188 BrowserThread::IO, FROM_HERE,
189 base::Bind(&BackgroundFetchRequestInfo::SetDownloadStatePopulated,
190 request));
175 191
176 // TODO(peter): The above two DCHECKs are assumptions our implementation 192 // TODO(peter): The above two DCHECKs are assumptions our implementation
177 // currently makes, but are not fit for production. We need to handle such 193 // currently makes, but are not fit for production. We need to handle such
178 // failures gracefully. 194 // failures gracefully.
179 195
180 // Register for updates on the download's progress. 196 // Register for updates on the download's progress.
181 download_item->AddObserver(this); 197 download_item->AddObserver(this);
182 198
183 // Inform the host about the |request| having started. 199 // Inform the host about the |request| having started.
184 BrowserThread::PostTask( 200 BrowserThread::PostTask(
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 completed_callback_(std::move(completed_callback)), 242 completed_callback_(std::move(completed_callback)),
227 traffic_annotation_(traffic_annotation), 243 traffic_annotation_(traffic_annotation),
228 weak_ptr_factory_(this) { 244 weak_ptr_factory_(this) {
229 DCHECK_CURRENTLY_ON(BrowserThread::IO); 245 DCHECK_CURRENTLY_ON(BrowserThread::IO);
230 246
231 // Create the core, containing the internal functionality that will have to 247 // Create the core, containing the internal functionality that will have to
232 // be run on the UI thread. It will respond to this class with a weak pointer. 248 // be run on the UI thread. It will respond to this class with a weak pointer.
233 ui_core_.reset(new Core(weak_ptr_factory_.GetWeakPtr(), registration_id, 249 ui_core_.reset(new Core(weak_ptr_factory_.GetWeakPtr(), registration_id,
234 browser_context, std::move(request_context))); 250 browser_context, std::move(request_context)));
235 251
236 // Get a WeakPtr over which we can talk to the |ui_core_|. 252 // Get a WeakPtr over which we can talk to the |ui_core_|. Normally it would
237 ui_core_ptr_ = ui_core_->GetWeakPtr(); 253 // be unsafe to obtain a weak pointer on the IO thread from a factory that
254 // lives on the UI thread, but it's ok in this constructor since the Core
255 // can't be destroyed before this constructor finishes.
256 ui_core_ptr_ = ui_core_->GetWeakPtrOnUI();
238 } 257 }
239 258
240 BackgroundFetchJobController::~BackgroundFetchJobController() = default; 259 BackgroundFetchJobController::~BackgroundFetchJobController() {
260 DCHECK_CURRENTLY_ON(BrowserThread::IO);
261 };
241 262
242 void BackgroundFetchJobController::Start( 263 void BackgroundFetchJobController::Start(
243 std::vector<scoped_refptr<BackgroundFetchRequestInfo>> initial_requests) { 264 std::vector<scoped_refptr<BackgroundFetchRequestInfo>> initial_requests) {
244 DCHECK_CURRENTLY_ON(BrowserThread::IO); 265 DCHECK_CURRENTLY_ON(BrowserThread::IO);
245 DCHECK_LE(initial_requests.size(), kMaximumBackgroundFetchParallelRequests); 266 DCHECK_LE(initial_requests.size(), kMaximumBackgroundFetchParallelRequests);
246 DCHECK_EQ(state_, State::INITIALIZED); 267 DCHECK_EQ(state_, State::INITIALIZED);
247 268
248 state_ = State::FETCHING; 269 state_ = State::FETCHING;
249 270
250 for (const auto& request : initial_requests) 271 for (const auto& request : initial_requests)
(...skipping 26 matching lines...) Expand all
277 pending_completed_file_acknowledgements_++; 298 pending_completed_file_acknowledgements_++;
278 299
279 data_manager_->MarkRequestAsCompleteAndGetNextRequest( 300 data_manager_->MarkRequestAsCompleteAndGetNextRequest(
280 registration_id_, request.get(), 301 registration_id_, request.get(),
281 base::BindOnce(&BackgroundFetchJobController::DidGetNextRequest, 302 base::BindOnce(&BackgroundFetchJobController::DidGetNextRequest,
282 weak_ptr_factory_.GetWeakPtr())); 303 weak_ptr_factory_.GetWeakPtr()));
283 } 304 }
284 305
285 void BackgroundFetchJobController::DidGetNextRequest( 306 void BackgroundFetchJobController::DidGetNextRequest(
286 scoped_refptr<BackgroundFetchRequestInfo> request) { 307 scoped_refptr<BackgroundFetchRequestInfo> request) {
308 DCHECK_CURRENTLY_ON(BrowserThread::IO);
287 DCHECK_LE(pending_completed_file_acknowledgements_, 1); 309 DCHECK_LE(pending_completed_file_acknowledgements_, 1);
288 pending_completed_file_acknowledgements_--; 310 pending_completed_file_acknowledgements_--;
289 311
290 // If a |request| has been given, start downloading the file and bail. 312 // If a |request| has been given, start downloading the file and bail.
291 if (request) { 313 if (request) {
292 StartRequest(std::move(request)); 314 StartRequest(std::move(request));
293 return; 315 return;
294 } 316 }
295 317
296 // If there are outstanding completed file acknowlegements, bail as well. 318 // If there are outstanding completed file acknowlegements, bail as well.
(...skipping 17 matching lines...) Expand all
314 336
315 // TODO(harkness): Abort all in-progress downloads. 337 // TODO(harkness): Abort all in-progress downloads.
316 338
317 state_ = State::ABORTED; 339 state_ = State::ABORTED;
318 340
319 // Inform the owner of the controller about the job having completed. 341 // Inform the owner of the controller about the job having completed.
320 std::move(completed_callback_).Run(this); 342 std::move(completed_callback_).Run(this);
321 } 343 }
322 344
323 } // namespace content 345 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698