| OLD | NEW |
| 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 #ifndef BodyStreamBuffer_h | 5 #ifndef BodyStreamBuffer_h |
| 6 #define BodyStreamBuffer_h | 6 #define BodyStreamBuffer_h |
| 7 | 7 |
| 8 #include "core/dom/DOMException.h" | 8 #include "core/dom/DOMException.h" |
| 9 #include "core/streams/ReadableByteStream.h" |
| 10 #include "core/streams/ReadableByteStreamReader.h" |
| 11 #include "core/streams/UnderlyingSource.h" |
| 9 #include "modules/ModulesExport.h" | 12 #include "modules/ModulesExport.h" |
| 10 #include "modules/fetch/DataConsumerHandleUtil.h" | |
| 11 #include "modules/fetch/FetchDataConsumerHandle.h" | 13 #include "modules/fetch/FetchDataConsumerHandle.h" |
| 12 #include "modules/fetch/FetchDataLoader.h" | 14 #include "modules/fetch/FetchDataLoader.h" |
| 13 #include "platform/blob/BlobData.h" | 15 #include "platform/heap/Handle.h" |
| 14 #include "platform/heap/Heap.h" | |
| 15 #include "public/platform/WebDataConsumerHandle.h" | 16 #include "public/platform/WebDataConsumerHandle.h" |
| 16 #include "wtf/Deque.h" | 17 #include "wtf/OwnPtr.h" |
| 17 #include "wtf/RefPtr.h" | 18 #include "wtf/PassOwnPtr.h" |
| 18 #include "wtf/text/WTFString.h" | |
| 19 | 19 |
| 20 namespace blink { | 20 namespace blink { |
| 21 | 21 |
| 22 class DrainingBodyStreamBuffer; | 22 class ExecutionContext; |
| 23 | 23 |
| 24 class MODULES_EXPORT BodyStreamBuffer final : public GarbageCollectedFinalized<B
odyStreamBuffer> { | 24 // A BodyStreamBuffer constructed with a null handle is said to have null body. |
| 25 // One can observe if a buffer has null body by calling |hasBody| function. |
| 26 // |stream| function returns a non-null stream even when the buffer has null |
| 27 // body. |
| 28 class MODULES_EXPORT BodyStreamBuffer final : public GarbageCollectedFinalized<B
odyStreamBuffer>, public UnderlyingSource, public WebDataConsumerHandle::Client
{ |
| 29 WTF_MAKE_NONCOPYABLE(BodyStreamBuffer); |
| 30 USING_GARBAGE_COLLECTED_MIXIN(BodyStreamBuffer); |
| 25 public: | 31 public: |
| 26 static BodyStreamBuffer* create(PassOwnPtr<FetchDataConsumerHandle> handle)
{ return new BodyStreamBuffer(handle); } | 32 BodyStreamBuffer() : BodyStreamBuffer(nullptr) {} |
| 27 static BodyStreamBuffer* createEmpty(); | 33 // |handle| can be null, but cannot be locked. |
| 34 explicit BodyStreamBuffer(PassOwnPtr<FetchDataConsumerHandle> /* handle */); |
| 28 | 35 |
| 29 FetchDataConsumerHandle* handle() const; | 36 ReadableByteStream* stream() { return m_stream; } |
| 30 PassOwnPtr<FetchDataConsumerHandle> releaseHandle(); | |
| 31 | 37 |
| 32 class MODULES_EXPORT DrainingStreamNotificationClient : public GarbageCollec
tedMixin { | 38 // Callable only when not locked. |
| 33 public: | 39 PassRefPtr<BlobDataHandle> drainAsBlobDataHandle(FetchDataConsumerHandle::Re
ader::BlobSizePolicy); |
| 34 virtual ~DrainingStreamNotificationClient() { } | 40 |
| 35 // Called after FetchDataLoader::Client methods. | 41 // Callable only when not locked. Returns a non-null handle even when |
| 36 virtual void didFetchDataLoadFinishedFromDrainingStream() = 0; | 42 // having null body. |
| 37 }; | 43 // Note: There is a case that calling |lock| doesn't make the buffer |
| 44 // locked. |unlock| should be called even in such cases when a user finishes |
| 45 // to use the returned handle, in order to maintain hasPendingActivity(). |
| 46 PassOwnPtr<FetchDataConsumerHandle> lock(ExecutionContext*); |
| 47 |
| 48 // This function will lock |this| object. |client| cannot be null. |
| 49 void startLoading(ExecutionContext*, FetchDataLoader*, FetchDataLoader::Clie
nt* /* client */); |
| 50 |
| 51 bool isLocked() const { return m_stream->isLocked(); } |
| 52 bool hasBody() const { return m_hasBody; } |
| 53 bool hasPendingActivity() const { return isLocked() || m_lockLevel > 0; } |
| 54 |
| 55 // UnderlyingSource |
| 56 void pullSource() override; |
| 57 ScriptPromise cancelSource(ScriptState*, ScriptValue reason) override; |
| 58 |
| 59 // WebDataConsumerHandle::Client |
| 60 void didGetReadable() override; |
| 38 | 61 |
| 39 DEFINE_INLINE_TRACE() | 62 DEFINE_INLINE_TRACE() |
| 40 { | 63 { |
| 41 visitor->trace(m_fetchDataLoader); | 64 visitor->trace(m_stream); |
| 42 visitor->trace(m_drainingStreamNotificationClient); | 65 visitor->trace(m_streamReader); |
| 66 visitor->trace(m_loaders); |
| 67 UnderlyingSource::trace(visitor); |
| 43 } | 68 } |
| 44 | 69 |
| 45 void didFetchDataLoadFinished(); | |
| 46 | |
| 47 private: | 70 private: |
| 48 explicit BodyStreamBuffer(PassOwnPtr<FetchDataConsumerHandle> handle) : m_ha
ndle(handle) { } | 71 class LoaderHolder; |
| 49 | 72 enum EndLoadingMode { |
| 50 void setDrainingStreamNotificationClient(DrainingStreamNotificationClient*); | 73 EndLoadingDone, |
| 51 | 74 EndLoadingErrored, |
| 52 void startLoading(FetchDataLoader*, FetchDataLoader::Client*); | 75 }; |
| 53 // Call DrainingStreamNotificationClient. | 76 void close(); |
| 54 void doDrainingStreamNotification(); | 77 void error(); |
| 55 // Clear DrainingStreamNotificationClient without calling. | 78 void processData(); |
| 56 void clearDrainingStreamNotification(); | 79 void unlock(); |
| 57 | 80 void endLoading(FetchDataLoader::Client*, EndLoadingMode); |
| 58 friend class DrainingBodyStreamBuffer; | |
| 59 | 81 |
| 60 OwnPtr<FetchDataConsumerHandle> m_handle; | 82 OwnPtr<FetchDataConsumerHandle> m_handle; |
| 61 Member<FetchDataLoader> m_fetchDataLoader; | 83 OwnPtr<FetchDataConsumerHandle::Reader> m_reader; |
| 62 Member<DrainingStreamNotificationClient> m_drainingStreamNotificationClient; | 84 Member<ReadableByteStream> m_stream; |
| 63 }; | 85 Member<ReadableByteStreamReader> m_streamReader; |
| 64 | 86 HeapHashSet<Member<FetchDataLoader::Client>> m_loaders; |
| 65 // DrainingBodyStreamBuffer wraps BodyStreamBuffer returned from | 87 // We need this variable because we cannot lock closed or erroed stream |
| 66 // Body::createDrainingStream() and calls DrainingStreamNotificationClient | 88 // although we should return true for hasPendingActivity() when someone |
| 67 // callbacks unless leakBuffer() is called: | 89 // calls |startLoading| but the loding is not yet done. |
| 68 // - If startLoading() is called, the callback is called after loading finished. | 90 unsigned m_lockLevel; |
| 69 // - If drainAsBlobDataHandle() is called, the callback is called immediately. | 91 const bool m_hasBody; |
| 70 // - If leakBuffer() is called, the callback is no longer called. | 92 bool m_streamNeedsMore; |
| 71 // Any calls to DrainingBodyStreamBuffer methods after a call to either of | |
| 72 // methods above is no-op. | |
| 73 // After calling one of the methods above, we don't have to keep | |
| 74 // DrainingBodyStreamBuffer alive. | |
| 75 // If DrainingBodyStreamBuffer is destructed before any of above is called, | |
| 76 // the callback is called at destruction. | |
| 77 class MODULES_EXPORT DrainingBodyStreamBuffer final { | |
| 78 public: | |
| 79 static PassOwnPtr<DrainingBodyStreamBuffer> create(BodyStreamBuffer* buffer,
BodyStreamBuffer::DrainingStreamNotificationClient* client) | |
| 80 { | |
| 81 return adoptPtr(new DrainingBodyStreamBuffer(buffer, client)); | |
| 82 } | |
| 83 ~DrainingBodyStreamBuffer(); | |
| 84 void startLoading(FetchDataLoader*, FetchDataLoader::Client*); | |
| 85 BodyStreamBuffer* leakBuffer(); | |
| 86 PassRefPtr<BlobDataHandle> drainAsBlobDataHandle(FetchDataConsumerHandle::Re
ader::BlobSizePolicy); | |
| 87 | |
| 88 private: | |
| 89 DrainingBodyStreamBuffer(BodyStreamBuffer*, BodyStreamBuffer::DrainingStream
NotificationClient*); | |
| 90 | |
| 91 Persistent<BodyStreamBuffer> m_buffer; | |
| 92 }; | 93 }; |
| 93 | 94 |
| 94 } // namespace blink | 95 } // namespace blink |
| 95 | 96 |
| 96 #endif // BodyStreamBuffer_h | 97 #endif // BodyStreamBuffer_h |
| OLD | NEW |