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

Side by Side Diff: Source/modules/fetch/Body.cpp

Issue 899653002: Use ExclusiveStreamReader to lock Body. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@exclusive-reader
Patch Set: rebase Created 5 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
« no previous file with comments | « Source/modules/fetch/Body.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "config.h" 5 #include "config.h"
6 #include "modules/fetch/Body.h" 6 #include "modules/fetch/Body.h"
7 7
8 #include "bindings/core/v8/ExceptionState.h" 8 #include "bindings/core/v8/ExceptionState.h"
9 #include "bindings/core/v8/ScriptPromiseResolver.h" 9 #include "bindings/core/v8/ScriptPromiseResolver.h"
10 #include "bindings/core/v8/ScriptState.h" 10 #include "bindings/core/v8/ScriptState.h"
11 #include "bindings/core/v8/V8ArrayBuffer.h" 11 #include "bindings/core/v8/V8ArrayBuffer.h"
12 #include "bindings/core/v8/V8ThrowException.h" 12 #include "bindings/core/v8/V8ThrowException.h"
13 #include "core/dom/DOMArrayBuffer.h" 13 #include "core/dom/DOMArrayBuffer.h"
14 #include "core/fileapi/Blob.h" 14 #include "core/fileapi/Blob.h"
15 #include "core/fileapi/FileReaderLoader.h" 15 #include "core/fileapi/FileReaderLoader.h"
16 #include "core/fileapi/FileReaderLoaderClient.h" 16 #include "core/fileapi/FileReaderLoaderClient.h"
17 #include "core/frame/UseCounter.h" 17 #include "core/frame/UseCounter.h"
18 #include "core/streams/ExclusiveStreamReader.h"
18 #include "core/streams/UnderlyingSource.h" 19 #include "core/streams/UnderlyingSource.h"
19 #include "modules/fetch/BodyStreamBuffer.h" 20 #include "modules/fetch/BodyStreamBuffer.h"
20 21
21 namespace blink { 22 namespace blink {
22 23
23 class Body::BlobHandleReceiver final : public BodyStreamBuffer::BlobHandleCreato rClient { 24 class Body::BlobHandleReceiver final : public BodyStreamBuffer::BlobHandleCreato rClient {
24 public: 25 public:
25 explicit BlobHandleReceiver(Body* body) 26 explicit BlobHandleReceiver(Body* body)
26 : m_body(body) 27 : m_body(body)
27 { 28 {
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 // Created when createDrainingStream is called to drain the data. 227 // Created when createDrainingStream is called to drain the data.
227 Member<BodyStreamBuffer> m_drainingStreamBuffer; 228 Member<BodyStreamBuffer> m_drainingStreamBuffer;
228 Member<ReadableStreamImpl<ReadableStreamChunkTypeTraits<DOMArrayBuffer>>> m_ stream; 229 Member<ReadableStreamImpl<ReadableStreamChunkTypeTraits<DOMArrayBuffer>>> m_ stream;
229 State m_state; 230 State m_state;
230 // The count of the chunks which were enqueued to the ReadableStream. 231 // The count of the chunks which were enqueued to the ReadableStream.
231 size_t m_queueCount; 232 size_t m_queueCount;
232 }; 233 };
233 234
234 ScriptPromise Body::readAsync(ScriptState* scriptState, ResponseType type) 235 ScriptPromise Body::readAsync(ScriptState* scriptState, ResponseType type)
235 { 236 {
236 if (m_bodyUsed) 237 if (bodyUsed())
237 return ScriptPromise::reject(scriptState, V8ThrowException::createTypeEr ror(scriptState->isolate(), "Already read")); 238 return ScriptPromise::reject(scriptState, V8ThrowException::createTypeEr ror(scriptState->isolate(), "Already read"));
238 239
239 // When the main thread sends a V8::TerminateExecution() signal to a worker 240 // When the main thread sends a V8::TerminateExecution() signal to a worker
240 // thread, any V8 API on the worker thread starts returning an empty 241 // thread, any V8 API on the worker thread starts returning an empty
241 // handle. This can happen in Body::readAsync. To avoid the situation, we 242 // handle. This can happen in Body::readAsync. To avoid the situation, we
242 // first check the ExecutionContext and return immediately if it's already 243 // first check the ExecutionContext and return immediately if it's already
243 // gone (which means that the V8::TerminateExecution() signal has been sent 244 // gone (which means that the V8::TerminateExecution() signal has been sent
244 // to this worker thread). 245 // to this worker thread).
245 ExecutionContext* executionContext = scriptState->executionContext(); 246 ExecutionContext* executionContext = scriptState->executionContext();
246 if (!executionContext) 247 if (!executionContext)
247 return ScriptPromise(); 248 return ScriptPromise();
248 249
249 m_bodyUsed = true; 250 setBodyUsed();
250 m_responseType = type; 251 m_responseType = type;
251 252
252 ASSERT(!m_resolver); 253 ASSERT(!m_resolver);
253 m_resolver = ScriptPromiseResolver::create(scriptState); 254 m_resolver = ScriptPromiseResolver::create(scriptState);
254 ScriptPromise promise = m_resolver->promise(); 255 ScriptPromise promise = m_resolver->promise();
255 256
256 if (m_stream) { 257 if (m_stream) {
257 ASSERT(m_streamSource); 258 ASSERT(m_streamSource);
258 bool dataLost; 259 bool dataLost;
259 m_streamSource->createDrainingStream(&dataLost)->readAllAndCreateBlobHan dle(contentTypeForBuffer(), new BlobHandleReceiver(this)); 260 m_streamSource->createDrainingStream(&dataLost)->readAllAndCreateBlobHan dle(contentTypeForBuffer(), new BlobHandleReceiver(this));
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
339 ASSERT(!m_streamSource); 340 ASSERT(!m_streamSource);
340 m_streamSource = new ReadableStreamSource(this); 341 m_streamSource = new ReadableStreamSource(this);
341 m_stream = new ReadableStreamImpl<ReadableStreamChunkTypeTraits<DOMArray Buffer>>(executionContext(), m_streamSource); 342 m_stream = new ReadableStreamImpl<ReadableStreamChunkTypeTraits<DOMArray Buffer>>(executionContext(), m_streamSource);
342 m_streamSource->startStream(m_stream); 343 m_streamSource->startStream(m_stream);
343 } 344 }
344 return m_stream; 345 return m_stream;
345 } 346 }
346 347
347 bool Body::bodyUsed() const 348 bool Body::bodyUsed() const
348 { 349 {
349 return m_bodyUsed; 350 return m_bodyUsed || (m_stream && m_stream->isLocked());
350 } 351 }
351 352
352 void Body::setBodyUsed() 353 void Body::setBodyUsed()
353 { 354 {
355 ASSERT(!m_bodyUsed);
356 ASSERT(!m_stream || !m_stream->isLocked());
357 // Note that technically we can set BodyUsed even when the stream is
358 // closed or errored, but getReader doesn't work then.
359 if (m_stream && m_stream->stateInternal() != ReadableStream::Closed && m_str eam->stateInternal() != ReadableStream::Errored) {
360 TrackExceptionState exceptionState;
361 m_streamReader = m_stream->getReader(exceptionState);
362 ASSERT(!exceptionState.hadException());
363 }
354 m_bodyUsed = true; 364 m_bodyUsed = true;
355 } 365 }
356 366
357 bool Body::streamAccessed() const 367 bool Body::streamAccessed() const
358 { 368 {
359 return m_stream; 369 return m_stream;
360 } 370 }
361 371
362 BodyStreamBuffer* Body::createDrainingStream(bool* dataLost) 372 BodyStreamBuffer* Body::createDrainingStream(bool* dataLost)
363 { 373 {
(...skipping 20 matching lines...) Expand all
384 if (m_stream && m_stream->hasPendingActivity()) 394 if (m_stream && m_stream->hasPendingActivity())
385 return true; 395 return true;
386 return false; 396 return false;
387 } 397 }
388 398
389 DEFINE_TRACE(Body) 399 DEFINE_TRACE(Body)
390 { 400 {
391 visitor->trace(m_resolver); 401 visitor->trace(m_resolver);
392 visitor->trace(m_stream); 402 visitor->trace(m_stream);
393 visitor->trace(m_streamSource); 403 visitor->trace(m_streamSource);
404 visitor->trace(m_streamReader);
394 ActiveDOMObject::trace(visitor); 405 ActiveDOMObject::trace(visitor);
395 } 406 }
396 407
397 Body::Body(ExecutionContext* context) 408 Body::Body(ExecutionContext* context)
398 : ActiveDOMObject(context) 409 : ActiveDOMObject(context)
399 , m_bodyUsed(false) 410 , m_bodyUsed(false)
400 , m_responseType(ResponseType::ResponseUnknown) 411 , m_responseType(ResponseType::ResponseUnknown)
401 { 412 {
402 } 413 }
403 414
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
476 487
477 void Body::didBlobHandleReceiveError(PassRefPtrWillBeRawPtr<DOMException> except ion) 488 void Body::didBlobHandleReceiveError(PassRefPtrWillBeRawPtr<DOMException> except ion)
478 { 489 {
479 if (!m_resolver) 490 if (!m_resolver)
480 return; 491 return;
481 m_resolver->reject(exception); 492 m_resolver->reject(exception);
482 m_resolver.clear(); 493 m_resolver.clear();
483 } 494 }
484 495
485 } // namespace blink 496 } // namespace blink
OLDNEW
« no previous file with comments | « Source/modules/fetch/Body.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698