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

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

Issue 2687083002: Headless: make URLRequestDispatcher aware of navigations (Closed)
Patch Set: Address nits 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
61 void DeterministicDispatcher::NavigationRequested(
62 std::unique_ptr<NavigationRequest> navigation) {
63 base::AutoLock lock(lock_);
64 pending_requests_.emplace_back(std::move(navigation));
65
66 MaybeDispatchJobLocked();
67 }
68
59 void DeterministicDispatcher::MaybeDispatchJobLocked() { 69 void DeterministicDispatcher::MaybeDispatchJobLocked() {
60 if (dispatch_pending_ || ready_status_map_.empty()) 70 if (dispatch_pending_ || navigation_in_progress_)
61 return; 71 return;
62 72
73 if (ready_status_map_.empty()) {
74 if (pending_requests_.empty())
75 return; // Nothing to do.
76
77 // Don't post a task if the first job is a url request (which isn't ready
78 // yet).
79 if (pending_requests_.front().url_request)
80 return;
81 }
82
63 dispatch_pending_ = true; 83 dispatch_pending_ = true;
64 io_thread_task_runner_->PostTask( 84 io_thread_task_runner_->PostTask(
65 FROM_HERE, 85 FROM_HERE,
66 base::Bind(&DeterministicDispatcher::MaybeDispatchJobOnIOThreadTask, 86 base::Bind(&DeterministicDispatcher::MaybeDispatchJobOnIOThreadTask,
67 weak_ptr_factory_.GetWeakPtr())); 87 weak_ptr_factory_.GetWeakPtr()));
68 } 88 }
69 89
70 void DeterministicDispatcher::MaybeDispatchJobOnIOThreadTask() { 90 void DeterministicDispatcher::MaybeDispatchJobOnIOThreadTask() {
71 ManagedDispatchURLRequestJob* job; 91 Request request;
72 net::Error job_status; 92 net::Error job_status;
73 93
74 { 94 {
75 base::AutoLock lock(lock_); 95 base::AutoLock lock(lock_);
76 dispatch_pending_ = false; 96 dispatch_pending_ = false;
77 // If the job got deleted, |pending_requests_| may be empty. 97 // If the job got deleted, |pending_requests_| may be empty.
78 if (pending_requests_.empty()) 98 if (pending_requests_.empty())
79 return; 99 return;
80 job = pending_requests_.front(); 100
81 StatusMap::const_iterator it = ready_status_map_.find(job); 101 // 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. 102 if (navigation_in_progress_)
83 if (it == ready_status_map_.end())
84 return; 103 return;
85 104
86 job_status = it->second; 105 request = std::move(pending_requests_.front());
87 ready_status_map_.erase(it); 106 if (request.url_request) {
107 StatusMap::const_iterator it =
108 ready_status_map_.find(request.url_request);
109 // Bail out if the oldest job is not be ready for dispatch yet.
110 if (it == ready_status_map_.end())
111 return;
112
113 job_status = it->second;
114 ready_status_map_.erase(it);
115 } else {
116 DCHECK(!navigation_in_progress_);
117 navigation_in_progress_ = true;
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(
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 DCHECK(navigation_in_progress_);
139 navigation_in_progress_ = false;
140 }
141
142 MaybeDispatchJobLocked();
143 }
144
145 DeterministicDispatcher::Request::Request() : url_request(nullptr) {}
146 DeterministicDispatcher::Request::~Request() {}
147
148 DeterministicDispatcher::Request::Request(
149 ManagedDispatchURLRequestJob* url_request)
150 : url_request(url_request) {}
151
152 DeterministicDispatcher::Request::Request(
153 std::unique_ptr<NavigationRequest> navigation_request)
154 : url_request(nullptr), navigation_request(std::move(navigation_request)) {}
155
156 DeterministicDispatcher::Request& DeterministicDispatcher::Request::operator=(
157 DeterministicDispatcher::Request&& other) {
158 url_request = other.url_request;
159 navigation_request = std::move(other.navigation_request);
160 return *this;
161 }
162
98 } // namespace headless 163 } // namespace headless
OLDNEW
« no previous file with comments | « headless/public/util/deterministic_dispatcher.h ('k') | headless/public/util/deterministic_dispatcher_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698