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

Side by Side Diff: headless/public/util/deterministic_dispatcher.cc

Issue 2687083002: Headless: make URLRequestDispatcher aware of navigations (Closed)
Patch Set: Added ExpeditedDispatcherTest Created 3 years, 10 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 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "headless/public/util/deterministic_dispatcher.h" 5 #include "headless/public/util/deterministic_dispatcher.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "headless/public/util/managed_dispatch_url_request_job.h" 11 #include "headless/public/util/managed_dispatch_url_request_job.h"
12 #include "headless/public/util/navigation_request.h"
12 13
13 namespace headless { 14 namespace headless {
14 15
15 DeterministicDispatcher::DeterministicDispatcher( 16 DeterministicDispatcher::DeterministicDispatcher(
16 scoped_refptr<base::SingleThreadTaskRunner> io_thread_task_runner) 17 scoped_refptr<base::SingleThreadTaskRunner> io_thread_task_runner)
17 : io_thread_task_runner_(std::move(io_thread_task_runner)), 18 : io_thread_task_runner_(std::move(io_thread_task_runner)),
18 dispatch_pending_(false), 19 dispatch_pending_(false),
20 navigation_in_progress_(false),
19 weak_ptr_factory_(this) {} 21 weak_ptr_factory_(this) {}
20 22
21 DeterministicDispatcher::~DeterministicDispatcher() {} 23 DeterministicDispatcher::~DeterministicDispatcher() {}
22 24
23 void DeterministicDispatcher::JobCreated(ManagedDispatchURLRequestJob* job) { 25 void DeterministicDispatcher::JobCreated(ManagedDispatchURLRequestJob* job) {
24 base::AutoLock lock(lock_); 26 base::AutoLock lock(lock_);
25 pending_requests_.push_back(job); 27 pending_requests_.emplace_back(job);
26 } 28 }
27 29
28 void DeterministicDispatcher::JobKilled(ManagedDispatchURLRequestJob* job) { 30 void DeterministicDispatcher::JobKilled(ManagedDispatchURLRequestJob* job) {
29 base::AutoLock lock(lock_); 31 base::AutoLock lock(lock_);
30 for (auto it = pending_requests_.begin(); it != pending_requests_.end(); 32 for (auto it = pending_requests_.begin(); it != pending_requests_.end();
31 it++) { 33 it++) {
32 if (*it == job) { 34 if (it->url_request == job) {
33 pending_requests_.erase(it); 35 pending_requests_.erase(it);
34 break; 36 break;
35 } 37 }
36 } 38 }
37 ready_status_map_.erase(job); 39 ready_status_map_.erase(job);
38 // We rely on JobDeleted getting called to call MaybeDispatchJobLocked. 40 // We rely on JobDeleted getting called to call MaybeDispatchJobLocked.
39 } 41 }
40 42
41 void DeterministicDispatcher::JobFailed(ManagedDispatchURLRequestJob* job, 43 void DeterministicDispatcher::JobFailed(ManagedDispatchURLRequestJob* job,
42 net::Error error) { 44 net::Error error) {
43 base::AutoLock lock(lock_); 45 base::AutoLock lock(lock_);
44 ready_status_map_[job] = error; 46 ready_status_map_[job] = error;
45 MaybeDispatchJobLocked(); 47 MaybeDispatchJobLocked();
46 } 48 }
47 49
48 void DeterministicDispatcher::DataReady(ManagedDispatchURLRequestJob* job) { 50 void DeterministicDispatcher::DataReady(ManagedDispatchURLRequestJob* job) {
49 base::AutoLock lock(lock_); 51 base::AutoLock lock(lock_);
50 ready_status_map_[job] = net::OK; 52 ready_status_map_[job] = net::OK;
51 MaybeDispatchJobLocked(); 53 MaybeDispatchJobLocked();
52 } 54 }
53 55
54 void DeterministicDispatcher::JobDeleted(ManagedDispatchURLRequestJob* job) { 56 void DeterministicDispatcher::JobDeleted(ManagedDispatchURLRequestJob* job) {
55 base::AutoLock lock(lock_); 57 base::AutoLock lock(lock_);
56 MaybeDispatchJobLocked(); 58 MaybeDispatchJobLocked();
57 } 59 }
58 60
59 void DeterministicDispatcher::MaybeDispatchJobLocked() { 61 void DeterministicDispatcher::NavigationRequested(
60 if (dispatch_pending_ || ready_status_map_.empty()) 62 std::unique_ptr<NavigationRequest> navigation) {
63 base::AutoLock lock(lock_);
64 pending_requests_.emplace_back(std::move(navigation));
65
66 MaybeDispatchNavigationJobLocked();
67 }
68
69 void DeterministicDispatcher::MaybeDispatchNavigationJobLocked() {
altimin 2017/02/09 12:01:52 I don't like two similar methods with subtle diffe
alex clarke (OOO till 29th) 2017/02/09 12:44:43 OK I found a way of merging them.
70 if (dispatch_pending_ || navigation_in_progress_)
61 return; 71 return;
62 72
63 dispatch_pending_ = true; 73 dispatch_pending_ = true;
74 io_thread_task_runner_->PostTask(
75 FROM_HERE,
76 base::Bind(&DeterministicDispatcher::MaybeDispatchJobOnIOThreadTask,
77 weak_ptr_factory_.GetWeakPtr()));
78 }
79
80 void DeterministicDispatcher::MaybeDispatchJobLocked() {
81 if (dispatch_pending_ || navigation_in_progress_ || ready_status_map_.empty())
82 return;
83
84 dispatch_pending_ = true;
64 io_thread_task_runner_->PostTask( 85 io_thread_task_runner_->PostTask(
65 FROM_HERE, 86 FROM_HERE,
66 base::Bind(&DeterministicDispatcher::MaybeDispatchJobOnIOThreadTask, 87 base::Bind(&DeterministicDispatcher::MaybeDispatchJobOnIOThreadTask,
67 weak_ptr_factory_.GetWeakPtr())); 88 weak_ptr_factory_.GetWeakPtr()));
68 } 89 }
69 90
70 void DeterministicDispatcher::MaybeDispatchJobOnIOThreadTask() { 91 void DeterministicDispatcher::MaybeDispatchJobOnIOThreadTask() {
71 ManagedDispatchURLRequestJob* job; 92 Request request;
72 net::Error job_status; 93 net::Error job_status;
73 94
74 { 95 {
75 base::AutoLock lock(lock_); 96 base::AutoLock lock(lock_);
76 dispatch_pending_ = false; 97 dispatch_pending_ = false;
77 // If the job got deleted, |pending_requests_| may be empty. 98 // If the job got deleted, |pending_requests_| may be empty.
78 if (pending_requests_.empty()) 99 if (pending_requests_.empty())
79 return; 100 return;
80 job = pending_requests_.front(); 101
81 StatusMap::const_iterator it = ready_status_map_.find(job); 102 // Bail out if we're waiting for a navigation to complete.
82 // Bail out if the oldest job is not be ready for dispatch yet. 103 if (navigation_in_progress_)
83 if (it == ready_status_map_.end())
84 return; 104 return;
85 105
86 job_status = it->second; 106 request = std::move(pending_requests_.front());
87 ready_status_map_.erase(it); 107 if (request.url_request) {
108 StatusMap::const_iterator it =
109 ready_status_map_.find(request.url_request);
110 // Bail out if the oldest job is not be ready for dispatch yet.
111 if (it == ready_status_map_.end())
112 return;
113
114 job_status = it->second;
115 ready_status_map_.erase(it);
116 } else {
117 navigation_in_progress_ = true;
Sami 2017/02/09 12:03:26 DCHECK(!navigation_in_progress_)?
alex clarke (OOO till 29th) 2017/02/09 12:44:43 In theory this is guaranteed by line 103, but I su
118 }
88 pending_requests_.pop_front(); 119 pending_requests_.pop_front();
89 } 120 }
90 121
91 if (job_status == net::OK) { 122 if (request.url_request) {
92 job->OnHeadersComplete(); 123 if (job_status == net::OK) {
124 request.url_request->OnHeadersComplete();
125 } else {
126 request.url_request->OnStartError(job_status);
127 }
93 } else { 128 } else {
94 job->OnStartError(job_status); 129 request.navigation_request->StartProcessing(
altimin 2017/02/09 12:01:52 If we bailed in navigation_in_progress_, request.n
alex clarke (OOO till 29th) 2017/02/09 12:44:43 Not sure I follow. If we bail out, we exit the fu
altimin 2017/02/09 12:51:58 Sorry, got confused.
130 base::Bind(&DeterministicDispatcher::NavigationDoneTask,
131 weak_ptr_factory_.GetWeakPtr()));
95 } 132 }
96 } 133 }
97 134
135 void DeterministicDispatcher::NavigationDoneTask() {
136 {
137 base::AutoLock lock(lock_);
138 navigation_in_progress_ = false;
Sami 2017/02/09 12:03:26 DCHECK(navigation_in_progress_)?
alex clarke (OOO till 29th) 2017/02/09 12:44:43 Done.
139 }
140
141 MaybeDispatchNavigationJobLocked();
142 }
143
144 DeterministicDispatcher::Request::Request() : url_request(nullptr) {}
145 DeterministicDispatcher::Request::~Request() {}
146
147 DeterministicDispatcher::Request::Request(
148 ManagedDispatchURLRequestJob* url_request)
149 : url_request(url_request) {}
150
151 DeterministicDispatcher::Request::Request(
152 std::unique_ptr<NavigationRequest> navigation_request)
153 : url_request(nullptr), navigation_request(std::move(navigation_request)) {}
154
155 DeterministicDispatcher::Request& DeterministicDispatcher::Request::operator=(
156 DeterministicDispatcher::Request&& other) {
157 url_request = other.url_request;
158 navigation_request = std::move(other.navigation_request);
159 return *this;
160 }
161
98 } // namespace headless 162 } // namespace headless
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698