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

Side by Side Diff: content/browser/service_worker/service_worker_data_pipe_reader.cc

Issue 2703343002: ServiceWorker: Use mojo's data pipe for respondWith(stream) (Closed)
Patch Set: Rebase Created 3 years, 8 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "content/browser/service_worker/service_worker_data_pipe_reader.h"
6
7 #include "base/trace_event/trace_event.h"
8 #include "content/browser/service_worker/service_worker_url_request_job.h"
9 #include "content/browser/service_worker/service_worker_version.h"
10 #include "net/base/io_buffer.h"
11
12 namespace content {
13
14 ServiceWorkerDataPipeReader::ServiceWorkerDataPipeReader(
15 ServiceWorkerURLRequestJob* owner,
16 scoped_refptr<ServiceWorkerVersion> streaming_version,
17 blink::mojom::ServiceWorkerStreamHandlePtr stream_handle)
18 : owner_(owner),
19 streaming_version_(streaming_version),
20 handle_watcher_(FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::AUTOMATIC),
21 stream_(std::move(stream_handle->stream)),
22 binding_(this, std::move(stream_handle->callback_request)),
23 producer_state_(State::STREAMING) {
24 TRACE_EVENT_ASYNC_BEGIN1("ServiceWorker", "ServiceWorkerDataPipeReader", this,
25 "Url", owner->request()->url().spec());
26 streaming_version_->AddStreamingURLRequestJob(owner_);
27 binding_.set_connection_error_handler(base::Bind(
28 &ServiceWorkerDataPipeReader::OnAborted, base::Unretained(this)));
29 }
30
31 ServiceWorkerDataPipeReader::~ServiceWorkerDataPipeReader() {
32 if (streaming_version_) {
33 streaming_version_->RemoveStreamingURLRequestJob(owner_);
34 streaming_version_ = nullptr;
35 }
36 TRACE_EVENT_ASYNC_END0("ServiceWorker", "ServiceWorkerDataPipeReader", this);
37 }
38
39 void ServiceWorkerDataPipeReader::Start() {
40 TRACE_EVENT_ASYNC_STEP_INTO0("ServiceWorker", "ServiceWorkerDataPipeReader",
41 this, "Start");
42 handle_watcher_.Watch(
43 stream_.get(), MOJO_HANDLE_SIGNAL_READABLE,
44 base::Bind(&ServiceWorkerDataPipeReader::OnHandleGotReadable,
45 base::Unretained(this)));
46 owner_->OnResponseStarted();
47 }
48
49 void ServiceWorkerDataPipeReader::OnHandleGotReadable(MojoResult) {
horo 2017/04/06 05:22:08 DCHECK_EQ(State::STREAMING, producer_state_)?
shimazu 2017/04/07 08:52:29 Done.
50 TRACE_EVENT_ASYNC_STEP_INTO0("ServiceWorker", "ServiceWorkerDataPipeReader",
51 this, "OnHandleGotReadable");
52 // Do nothing if stream_pending_buffer_ is empty, i.e. there's no ReadRawData
53 // operation waiting for IO completion.
54 if (!stream_pending_buffer_)
55 return;
56
57 // |stream_pending_buffer_| is set to the IOBuffer instance provided to
58 // ReadRawData() by URLRequestJob.
59 uint32_t size_to_pass = stream_pending_buffer_size_;
60 MojoResult mojo_result =
61 mojo::ReadDataRaw(stream_.get(), stream_pending_buffer_->data(),
62 &size_to_pass, MOJO_READ_DATA_FLAG_NONE);
63
64 switch (mojo_result) {
65 case MOJO_RESULT_OK:
66 stream_pending_buffer_ = nullptr;
67 stream_pending_buffer_size_ = 0;
68 owner_->OnReadRawDataComplete(size_to_pass);
69 return;
70 case MOJO_RESULT_FAILED_PRECONDITION:
71 stream_.reset();
72 handle_watcher_.Cancel();
73 MaybeComplete();
74 return;
75 case MOJO_RESULT_SHOULD_WAIT:
76 return;
77 case MOJO_RESULT_BUSY:
78 case MOJO_RESULT_RESOURCE_EXHAUSTED:
horo 2017/04/06 05:22:08 mojo::ReadDataRaw doesn't return MOJO_RESULT_RESOU
shimazu 2017/04/07 08:52:29 Done.
79 stream_pending_buffer_ = nullptr;
80 stream_pending_buffer_size_ = 0;
81 stream_.reset();
82 handle_watcher_.Cancel();
83 owner_->OnReadRawDataComplete(net::ERR_FAILED);
84 return;
85 }
horo 2017/04/06 05:22:08 ASSERT_NOT_REACHED();
shimazu 2017/04/07 08:52:29 Done.
86 }
87
88 int ServiceWorkerDataPipeReader::ReadRawData(net::IOBuffer* buf, int buf_size) {
89 TRACE_EVENT_ASYNC_STEP_INTO0("ServiceWorker", "ServiceWorkerDataPipeReader",
90 this, "ReadRawData");
91 if (producer_state_ == State::ABORTED) {
92 // ABORT has been already notified.
93 // Handle this as connection reset.
94 stream_.reset();
95 handle_watcher_.Cancel();
96 owner_->RecordResult(
97 ServiceWorkerMetrics::REQUEST_JOB_ERROR_STREAM_ABORTED);
98 return net::ERR_CONNECTION_RESET;
99 }
100
101 uint32_t size_to_pass = buf_size;
102 MojoResult mojo_result = mojo::ReadDataRaw(
103 stream_.get(), buf->data(), &size_to_pass, MOJO_READ_DATA_FLAG_NONE);
104 switch (mojo_result) {
105 case MOJO_RESULT_OK:
106 return size_to_pass;
107 case MOJO_RESULT_FAILED_PRECONDITION:
108 stream_.reset();
109 handle_watcher_.Cancel();
110 if (state() == State::COMPLETED)
111 return 0;
112 // Complete/Abort asynchronously.
113 stream_pending_buffer_ = buf;
114 stream_pending_buffer_size_ = buf_size;
115 return net::ERR_IO_PENDING;
116 case MOJO_RESULT_BUSY:
117 return net::ERR_FAILED;
118 case MOJO_RESULT_SHOULD_WAIT:
119 stream_pending_buffer_ = buf;
120 stream_pending_buffer_size_ = buf_size;
121 return net::ERR_IO_PENDING;
122 case MOJO_RESULT_RESOURCE_EXHAUSTED:
horo 2017/04/06 05:22:08 mojo::ReadDataRaw doesn't return MOJO_RESULT_RESOU
shimazu 2017/04/07 08:52:29 Done.
123 return net::ERR_FAILED;
124 }
125 return net::ERR_FAILED;
horo 2017/04/06 05:22:08 ASSERT_NOT_REACHED();?
shimazu 2017/04/07 08:52:29 Done.
126 }
127
128 void ServiceWorkerDataPipeReader::OnCompleted() {
129 producer_state_ = State::COMPLETED;
130 MaybeComplete();
131 }
132
133 void ServiceWorkerDataPipeReader::OnAborted() {
134 producer_state_ = State::ABORTED;
135 MaybeComplete();
136 }
137
138 void ServiceWorkerDataPipeReader::MaybeComplete() {
139 // This works only after ReadRawData returns net::ERR_IO_PENDING.
140 if (!stream_pending_buffer_)
141 return;
142
143 switch (state()) {
144 case State::STREAMING:
145 return;
146 case State::COMPLETED:
147 stream_pending_buffer_ = nullptr;
148 stream_pending_buffer_size_ = 0;
149 handle_watcher_.Cancel();
150 owner_->RecordResult(ServiceWorkerMetrics::REQUEST_JOB_STREAM_RESPONSE);
151 owner_->OnReadRawDataComplete(0);
152 return;
153 case State::ABORTED:
154 stream_pending_buffer_ = nullptr;
155 stream_pending_buffer_size_ = 0;
156 handle_watcher_.Cancel();
157 owner_->RecordResult(
158 ServiceWorkerMetrics::REQUEST_JOB_ERROR_STREAM_ABORTED);
159 owner_->OnReadRawDataComplete(net::ERR_CONNECTION_RESET);
160 return;
161 }
162 }
163
164 ServiceWorkerDataPipeReader::State ServiceWorkerDataPipeReader::state() {
165 if (!stream_.is_valid())
166 return producer_state_;
167 return State::STREAMING;
168 }
169
170 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698