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

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

Issue 2703343002: ServiceWorker: Use mojo's data pipe for respondWith(stream) (Closed)
Patch Set: Addressed comments from kinuko and haraken 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 2016 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_stream_reader.h"
6
7 #include "content/browser/resource_context_impl.h"
8 #include "content/browser/service_worker/service_worker_version.h"
9 #include "content/browser/streams/stream.h"
10 #include "content/browser/streams/stream_context.h"
11 #include "content/browser/streams/stream_registry.h"
12 #include "net/base/io_buffer.h"
13
14 namespace content {
15
16 ServiceWorkerStreamReader::ServiceWorkerStreamReader(
17 ServiceWorkerURLRequestJob* owner,
18 scoped_refptr<ServiceWorkerVersion> streaming_version)
19 : owner_(owner),
20 stream_pending_buffer_size_(0),
21 streaming_version_(streaming_version) {
22 streaming_version_->AddStreamingURLRequestJob(owner_);
23 }
24
25 ServiceWorkerStreamReader::~ServiceWorkerStreamReader() {
26 if (streaming_version_) {
27 streaming_version_->RemoveStreamingURLRequestJob(owner_);
28 streaming_version_ = nullptr;
29 }
30 if (stream_) {
31 stream_->RemoveReadObserver(this);
32 stream_->Abort();
33 stream_ = nullptr;
34 }
35 if (!waiting_stream_url_.is_empty()) {
36 StreamRegistry* stream_registry =
37 GetStreamContextForResourceContext(owner_->resource_context())
38 ->registry();
39 stream_registry->RemoveRegisterObserver(waiting_stream_url_);
40 stream_registry->AbortPendingStream(waiting_stream_url_);
41 }
42 }
43
44 void ServiceWorkerStreamReader::Start(const GURL& stream_url) {
45 DCHECK(!stream_);
46 DCHECK(waiting_stream_url_.is_empty());
47
48 StreamContext* stream_context =
49 GetStreamContextForResourceContext(owner_->resource_context());
50 stream_ = stream_context->registry()->GetStream(stream_url);
51 if (!stream_) {
52 waiting_stream_url_ = stream_url;
53 // Wait for StreamHostMsg_StartBuilding message from the ServiceWorker.
54 stream_context->registry()->SetRegisterObserver(waiting_stream_url_, this);
55 return;
56 }
57 stream_->SetReadObserver(this);
58 owner_->OnResponseStarted();
59 }
60
61 int ServiceWorkerStreamReader::ReadRawData(net::IOBuffer* buf, int buf_size) {
62 DCHECK(stream_);
63 DCHECK(waiting_stream_url_.is_empty());
64
65 int bytes_read = 0;
66 switch (stream_->ReadRawData(buf, buf_size, &bytes_read)) {
67 case Stream::STREAM_HAS_DATA:
68 DCHECK_GT(bytes_read, 0);
69 return bytes_read;
70 case Stream::STREAM_COMPLETE:
71 DCHECK_EQ(0, bytes_read);
72 owner_->RecordResult(ServiceWorkerMetrics::REQUEST_JOB_STREAM_RESPONSE);
73 return 0;
74 case Stream::STREAM_EMPTY:
75 stream_pending_buffer_ = buf;
76 stream_pending_buffer_size_ = buf_size;
77 return net::ERR_IO_PENDING;
78 case Stream::STREAM_ABORTED:
79 // Handle this as connection reset.
80 owner_->RecordResult(
81 ServiceWorkerMetrics::REQUEST_JOB_ERROR_STREAM_ABORTED);
82 return net::ERR_CONNECTION_RESET;
83 }
84 NOTREACHED();
85 return net::ERR_FAILED;
86 }
87
88 void ServiceWorkerStreamReader::OnDataAvailable(Stream* stream) {
89 // Do nothing if stream_pending_buffer_ is empty, i.e. there's no ReadRawData
90 // operation waiting for IO completion.
91 if (!stream_pending_buffer_)
92 return;
93
94 // stream_pending_buffer_ is set to the IOBuffer instance provided to
95 // ReadRawData() by URLRequestJob.
96
97 int result = 0;
98 switch (stream_->ReadRawData(stream_pending_buffer_.get(),
99 stream_pending_buffer_size_, &result)) {
100 case Stream::STREAM_HAS_DATA:
101 DCHECK_GT(result, 0);
102 break;
103 case Stream::STREAM_COMPLETE:
104 // Calling NotifyReadComplete with 0 signals completion.
105 DCHECK(!result);
106 owner_->RecordResult(ServiceWorkerMetrics::REQUEST_JOB_STREAM_RESPONSE);
107 break;
108 case Stream::STREAM_EMPTY:
109 NOTREACHED();
110 break;
111 case Stream::STREAM_ABORTED:
112 // Handle this as connection reset.
113 result = net::ERR_CONNECTION_RESET;
114 owner_->RecordResult(
115 ServiceWorkerMetrics::REQUEST_JOB_ERROR_STREAM_ABORTED);
116 break;
117 }
118
119 // Clear the buffers before notifying the read is complete, so that it is
120 // safe for the observer to read.
121 stream_pending_buffer_ = nullptr;
122 stream_pending_buffer_size_ = 0;
123 owner_->OnReadRawDataComplete(result);
124 }
125
126 void ServiceWorkerStreamReader::OnStreamRegistered(Stream* stream) {
127 StreamContext* stream_context =
128 GetStreamContextForResourceContext(owner_->resource_context());
129 stream_context->registry()->RemoveRegisterObserver(waiting_stream_url_);
130 waiting_stream_url_ = GURL();
131 stream_ = stream;
132 stream_->SetReadObserver(this);
133 owner_->OnResponseStarted();
134 }
135
136 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698