| Index: third_party/WebKit/Source/modules/fetch/DataConsumerTee.cpp
|
| diff --git a/third_party/WebKit/Source/modules/fetch/DataConsumerTee.cpp b/third_party/WebKit/Source/modules/fetch/DataConsumerTee.cpp
|
| index 8b335d42f85c5b98c7573833af61f6d1e61c465a..aa16d1fad44ed6a1f84c6c88adb1b0b3a93d9c32 100644
|
| --- a/third_party/WebKit/Source/modules/fetch/DataConsumerTee.cpp
|
| +++ b/third_party/WebKit/Source/modules/fetch/DataConsumerTee.cpp
|
| @@ -6,6 +6,7 @@
|
|
|
| #include "core/dom/ActiveDOMObject.h"
|
| #include "core/dom/ExecutionContext.h"
|
| +#include "core/dom/TaskRunnerHelper.h"
|
| #include "modules/fetch/DataConsumerHandleUtil.h"
|
| #include "modules/fetch/FetchBlobDataConsumerHandle.h"
|
| #include "platform/CrossThreadFunctional.h"
|
| @@ -183,9 +184,9 @@ public:
|
| // No client is registered.
|
| return;
|
| }
|
| - DCHECK(m_readerThread);
|
| - if (!m_readerThread->isCurrentThread()) {
|
| - m_readerThread->getWebTaskRunner()->postTask(BLINK_FROM_HERE, crossThreadBind(&DestinationContext::notify, wrapPassRefPtr(this)));
|
| + DCHECK(m_readerTaskRunner);
|
| + if (!m_readerTaskRunner->runsTasksOnCurrentThread()) {
|
| + m_readerTaskRunner->postTask(BLINK_FROM_HERE, crossThreadBind(&DestinationContext::notify, wrapPassRefPtr(this)));
|
| return;
|
| }
|
| }
|
| @@ -198,17 +199,17 @@ public:
|
|
|
| // The following functions don't use lock. They should be protected by the
|
| // caller.
|
| - void attachReader(WebDataConsumerHandle::Client* client)
|
| + void attachReader(WebDataConsumerHandle::Client* client, std::unique_ptr<WebTaskRunner> readerTaskRunner)
|
| {
|
| - DCHECK(!m_readerThread);
|
| + DCHECK(!m_readerTaskRunner);
|
| DCHECK(!m_client);
|
| - m_readerThread = Platform::current()->currentThread();
|
| + m_readerTaskRunner = std::move(readerTaskRunner);
|
| m_client = client;
|
| }
|
| void detachReader()
|
| {
|
| - DCHECK(m_readerThread && m_readerThread->isCurrentThread());
|
| - m_readerThread = nullptr;
|
| + DCHECK(m_readerTaskRunner && m_readerTaskRunner->runsTasksOnCurrentThread());
|
| + m_readerTaskRunner = nullptr;
|
| m_client = nullptr;
|
| }
|
| const std::unique_ptr<Vector<char>>& top() const { return m_queue.first(); }
|
| @@ -231,7 +232,7 @@ public:
|
| private:
|
| DestinationContext()
|
| : m_result(WebDataConsumerHandle::ShouldWait)
|
| - , m_readerThread(nullptr)
|
| + , m_readerTaskRunner(nullptr)
|
| , m_client(nullptr)
|
| , m_offset(0)
|
| , m_isTwoPhaseReadInProgress(false)
|
| @@ -242,19 +243,13 @@ private:
|
| {
|
| MutexLocker locker(m_mutex);
|
| DCHECK(!m_client);
|
| - DCHECK(!m_readerThread);
|
| + DCHECK(!m_readerTaskRunner);
|
| m_queue.clear();
|
| }
|
|
|
| Result m_result;
|
| Deque<std::unique_ptr<Vector<char>>> m_queue;
|
| - // Note: Holding a WebThread raw pointer is not generally safe, but we can
|
| - // do that in this case because:
|
| - // 1. Destructing a ReaderImpl when the bound thread ends is a user's
|
| - // responsibility.
|
| - // 2. |m_readerThread| will never be used after the associated reader is
|
| - // detached.
|
| - WebThread* m_readerThread;
|
| + std::unique_ptr<WebTaskRunner> m_readerTaskRunner;
|
| WebDataConsumerHandle::Client* m_client;
|
| size_t m_offset;
|
| bool m_isTwoPhaseReadInProgress;
|
| @@ -263,16 +258,13 @@ private:
|
|
|
| class DestinationReader final : public WebDataConsumerHandle::Reader {
|
| public:
|
| - DestinationReader(PassRefPtr<DestinationContext::Proxy> contextProxy, WebDataConsumerHandle::Client* client)
|
| + DestinationReader(PassRefPtr<DestinationContext::Proxy> contextProxy, WebDataConsumerHandle::Client* client, std::unique_ptr<WebTaskRunner> readerTaskRunner)
|
| : m_contextProxy(contextProxy)
|
| {
|
| MutexLocker locker(context()->mutex());
|
| - context()->attachReader(client);
|
| + context()->attachReader(client, readerTaskRunner->clone());
|
| if (client) {
|
| - // We need to use crossThreadBind here to retain the context. Note
|
| - // |context()| return value is of type DestinationContext*, not
|
| - // PassRefPtr<DestinationContext>.
|
| - Platform::current()->currentThread()->getWebTaskRunner()->postTask(BLINK_FROM_HERE, crossThreadBind(&DestinationContext::notify, wrapPassRefPtr(context())));
|
| + readerTaskRunner->postTask(BLINK_FROM_HERE, bind(&DestinationContext::notify, wrapPassRefPtr(context())));
|
| }
|
| }
|
| ~DestinationReader() override
|
| @@ -317,9 +309,9 @@ public:
|
| return wrapUnique(new DestinationHandle(contextProxy));
|
| }
|
|
|
| - std::unique_ptr<Reader> obtainReader(Client* client)
|
| + std::unique_ptr<Reader> obtainReader(Client* client, std::unique_ptr<WebTaskRunner> readerTaskRunner)
|
| {
|
| - return wrapUnique(new DestinationReader(m_contextProxy, client));
|
| + return wrapUnique(new DestinationReader(m_contextProxy, client, std::move(readerTaskRunner)));
|
| }
|
|
|
| private:
|
| @@ -341,7 +333,7 @@ public:
|
| ExecutionContext* executionContext)
|
| : ActiveDOMObject(executionContext)
|
| , m_root(root)
|
| - , m_reader(src->obtainReader(this))
|
| + , m_reader(src->obtainReader(this, TaskRunnerHelper::getUnthrottledTaskRunner(executionContext)->clone()))
|
| , m_dest1(dest1)
|
| , m_dest2(dest2)
|
| {
|
| @@ -422,7 +414,8 @@ void DataConsumerTee::create(ExecutionContext* executionContext, std::unique_ptr
|
|
|
| void DataConsumerTee::create(ExecutionContext* executionContext, std::unique_ptr<FetchDataConsumerHandle> src, std::unique_ptr<FetchDataConsumerHandle>* dest1, std::unique_ptr<FetchDataConsumerHandle>* dest2)
|
| {
|
| - RefPtr<BlobDataHandle> blobDataHandle = src->obtainFetchDataReader(nullptr)->drainAsBlobDataHandle(FetchDataConsumerHandle::Reader::AllowBlobWithInvalidSize);
|
| + std::unique_ptr<WebTaskRunner> readerTaskRunner = TaskRunnerHelper::getUnthrottledTaskRunner(executionContext)->clone();
|
| + RefPtr<BlobDataHandle> blobDataHandle = src->obtainFetchDataReader(nullptr, std::move(readerTaskRunner))->drainAsBlobDataHandle(FetchDataConsumerHandle::Reader::AllowBlobWithInvalidSize);
|
| if (blobDataHandle) {
|
| *dest1 = FetchBlobDataConsumerHandle::create(executionContext, blobDataHandle);
|
| *dest2 = FetchBlobDataConsumerHandle::create(executionContext, blobDataHandle);
|
|
|