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

Unified Diff: third_party/WebKit/Source/core/loader/WorkerThreadableLoader.cpp

Issue 2151173003: Move WorkerThreadable internal classes to Oilpan heap (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@onheap-threadable-loader-client-wrapper
Patch Set: rebase Created 4 years, 5 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/WebKit/Source/core/loader/WorkerThreadableLoader.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/WebKit/Source/core/loader/WorkerThreadableLoader.cpp
diff --git a/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.cpp b/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.cpp
index 35343b41a748d01cf95f976e26168e470322a0b7..19f24037ed37614081c54bad4e1f452ded5a2c7c 100644
--- a/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.cpp
+++ b/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.cpp
@@ -36,39 +36,181 @@
#include "core/timing/WorkerGlobalScopePerformance.h"
#include "core/workers/WorkerGlobalScope.h"
#include "core/workers/WorkerLoaderProxy.h"
-#include "core/workers/WorkerThread.h"
#include "platform/CrossThreadFunctional.h"
-#include "platform/WaitableEvent.h"
#include "platform/heap/SafePoint.h"
#include "platform/network/ResourceError.h"
#include "platform/network/ResourceRequest.h"
#include "platform/network/ResourceResponse.h"
#include "platform/network/ResourceTimingInfo.h"
#include "platform/weborigin/SecurityPolicy.h"
-#include "public/platform/Platform.h"
-#include "wtf/PtrUtil.h"
-#include "wtf/Vector.h"
#include "wtf/debug/Alias.h"
#include <memory>
namespace blink {
-static std::unique_ptr<Vector<char>> createVectorFromMemoryRegion(const char* data, unsigned dataLength)
+namespace {
+
+std::unique_ptr<Vector<char>> createVectorFromMemoryRegion(const char* data, unsigned dataLength)
{
std::unique_ptr<Vector<char>> buffer = wrapUnique(new Vector<char>(dataLength));
memcpy(buffer->data(), data, dataLength);
return buffer;
}
-WorkerThreadableLoader::WorkerThreadableLoader(WorkerGlobalScope& workerGlobalScope, ThreadableLoaderClient* client, const ThreadableLoaderOptions& options, const ResourceLoaderOptions& resourceLoaderOptions, BlockingBehavior blockingBehavior)
+} // namespace
+
+class WorkerThreadableLoader::AsyncTaskForwarder final : public WorkerThreadableLoader::TaskForwarder {
+public:
+ explicit AsyncTaskForwarder(PassRefPtr<WorkerLoaderProxy> loaderProxy)
+ : m_loaderProxy(loaderProxy)
+ {
+ DCHECK(isMainThread());
+ }
+ ~AsyncTaskForwarder() override
+ {
+ DCHECK(isMainThread());
+ }
+
+ void forwardTask(const WebTraceLocation& location, std::unique_ptr<ExecutionContextTask> task) override
+ {
+ DCHECK(isMainThread());
+ m_loaderProxy->postTaskToWorkerGlobalScope(location, std::move(task));
+ }
+ void forwardTaskWithDoneSignal(const WebTraceLocation& location, std::unique_ptr<ExecutionContextTask> task) override
+ {
+ DCHECK(isMainThread());
+ m_loaderProxy->postTaskToWorkerGlobalScope(location, std::move(task));
+ }
+ void abort() override
+ {
+ DCHECK(isMainThread());
+ }
+
+private:
+ RefPtr<WorkerLoaderProxy> m_loaderProxy;
+};
+
+struct WorkerThreadableLoader::TaskWithLocation final {
+ TaskWithLocation(const WebTraceLocation& location, std::unique_ptr<ExecutionContextTask> task)
+ : m_location(location)
+ , m_task(std::move(task))
+ {
+ }
+ TaskWithLocation(TaskWithLocation&& task)
+ : TaskWithLocation(task.m_location, std::move(task.m_task))
+ {
+ }
+ ~TaskWithLocation() = default;
+
+ WebTraceLocation m_location;
+ std::unique_ptr<ExecutionContextTask> m_task;
+};
+
+// Observing functions and wait() need to be called on the worker thread.
+// Setting functions and signal() need to be called on the main thread.
+// All observing functions must be called after wait() returns, and all
+// setting functions must be called before signal() is called.
+class WorkerThreadableLoader::WaitableEventWithTasks final : public ThreadSafeRefCounted<WaitableEventWithTasks> {
+public:
+ static PassRefPtr<WaitableEventWithTasks> create() { return adoptRef(new WaitableEventWithTasks); }
+
+ void signal()
+ {
+ DCHECK(isMainThread());
+ CHECK(!m_isSignalCalled);
+ m_isSignalCalled = true;
+ m_event.signal();
+ }
+ void wait()
+ {
+ DCHECK(!isMainThread());
+ CHECK(!m_isWaitDone);
+ m_event.wait();
+ m_isWaitDone = true;
+ }
+
+ // Observing functions
+ bool isAborted() const
+ {
+ DCHECK(!isMainThread());
+ CHECK(m_isWaitDone);
+ return m_isAborted;
+ }
+ Vector<TaskWithLocation> take()
+ {
+ DCHECK(!isMainThread());
+ CHECK(m_isWaitDone);
+ return std::move(m_tasks);
+ }
+
+ // Setting functions
+ void append(TaskWithLocation task)
+ {
+ DCHECK(isMainThread());
+ CHECK(!m_isSignalCalled);
+ m_tasks.append(std::move(task));
+ }
+ void setIsAborted()
+ {
+ DCHECK(isMainThread());
+ CHECK(!m_isSignalCalled);
+ m_isAborted = true;
+ }
+
+private:
+ WaitableEventWithTasks() {}
+
+ WaitableEvent m_event;
+ Vector<TaskWithLocation> m_tasks;
+ bool m_isAborted = false;
+ bool m_isSignalCalled = false;
+ bool m_isWaitDone = false;
+};
+
+class WorkerThreadableLoader::SyncTaskForwarder final : public WorkerThreadableLoader::TaskForwarder {
+public:
+ explicit SyncTaskForwarder(PassRefPtr<WaitableEventWithTasks> eventWithTasks)
+ : m_eventWithTasks(eventWithTasks)
+ {
+ DCHECK(isMainThread());
+ }
+ ~SyncTaskForwarder() override
+ {
+ DCHECK(isMainThread());
+ }
+
+ void forwardTask(const WebTraceLocation& location, std::unique_ptr<ExecutionContextTask> task) override
+ {
+ DCHECK(isMainThread());
+ m_eventWithTasks->append(TaskWithLocation(location, std::move(task)));
+ }
+ void forwardTaskWithDoneSignal(const WebTraceLocation& location, std::unique_ptr<ExecutionContextTask> task) override
+ {
+ DCHECK(isMainThread());
+ m_eventWithTasks->append(TaskWithLocation(location, std::move(task)));
+ m_eventWithTasks->signal();
+ }
+ void abort() override
+ {
+ DCHECK(isMainThread());
+ m_eventWithTasks->setIsAborted();
+ m_eventWithTasks->signal();
+ }
+
+private:
+ RefPtr<WaitableEventWithTasks> m_eventWithTasks;
+};
+
+WorkerThreadableLoader::WorkerThreadableLoader(
+ WorkerGlobalScope& workerGlobalScope,
+ ThreadableLoaderClient* client,
+ const ThreadableLoaderOptions& options,
+ const ResourceLoaderOptions& resourceLoaderOptions,
+ BlockingBehavior blockingBehavior)
: m_workerGlobalScope(&workerGlobalScope)
, m_workerClientWrapper(new ThreadableLoaderClientWrapper(workerGlobalScope, client))
+ , m_bridge(new Bridge(m_workerClientWrapper, workerGlobalScope.thread()->workerLoaderProxy(), options, resourceLoaderOptions, blockingBehavior))
{
- if (blockingBehavior == LoadAsynchronously) {
- m_bridge = new MainThreadAsyncBridge(workerGlobalScope, m_workerClientWrapper, options, resourceLoaderOptions);
- } else {
- m_bridge = new MainThreadSyncBridge(workerGlobalScope, m_workerClientWrapper, options, resourceLoaderOptions);
- }
}
void WorkerThreadableLoader::loadResourceSynchronously(WorkerGlobalScope& workerGlobalScope, const ResourceRequest& request, ThreadableLoaderClient& client, const ThreadableLoaderOptions& options, const ResourceLoaderOptions& resourceLoaderOptions)
@@ -81,7 +223,6 @@ WorkerThreadableLoader::~WorkerThreadableLoader()
{
DCHECK(m_workerClientWrapper->done());
m_bridge->destroy();
- m_bridge = nullptr;
}
void WorkerThreadableLoader::start(const ResourceRequest& request)
@@ -94,291 +235,319 @@ void WorkerThreadableLoader::start(const ResourceRequest& request)
void WorkerThreadableLoader::overrideTimeout(unsigned long timeoutMilliseconds)
{
- ASSERT(m_bridge);
m_bridge->overrideTimeout(timeoutMilliseconds);
}
void WorkerThreadableLoader::cancel()
{
- ASSERT(m_bridge);
m_bridge->cancel();
}
-WorkerThreadableLoader::MainThreadBridgeBase::MainThreadBridgeBase(
- ThreadableLoaderClientWrapper* workerClientWrapper,
- PassRefPtr<WorkerLoaderProxy> loaderProxy)
- : m_workerClientWrapper(workerClientWrapper)
+WorkerThreadableLoader::Bridge::Bridge(
+ ThreadableLoaderClientWrapper* clientWrapper,
+ PassRefPtr<WorkerLoaderProxy> loaderProxy,
+ const ThreadableLoaderOptions& threadableLoaderOptions,
+ const ResourceLoaderOptions& resourceLoaderOptions,
+ BlockingBehavior blockingBehavior)
+ : m_clientWrapper(clientWrapper)
, m_loaderProxy(loaderProxy)
+ , m_threadableLoaderOptions(threadableLoaderOptions)
+ , m_resourceLoaderOptions(resourceLoaderOptions)
+ , m_blockingBehavior(blockingBehavior)
{
- ASSERT(m_workerClientWrapper.get());
- ASSERT(m_loaderProxy.get());
+ DCHECK(!isMainThread());
}
-WorkerThreadableLoader::MainThreadBridgeBase::~MainThreadBridgeBase()
+WorkerThreadableLoader::Bridge::~Bridge()
{
+ DCHECK(!isMainThread());
+ DCHECK(!m_peer);
}
-void WorkerThreadableLoader::MainThreadBridgeBase::mainThreadCreateLoader(ThreadableLoaderOptions options, ResourceLoaderOptions resourceLoaderOptions, ExecutionContext* context)
+void WorkerThreadableLoader::Bridge::start(const ResourceRequest& request, const WorkerGlobalScope& workerGlobalScope)
{
- ASSERT(isMainThread());
- Document* document = toDocument(context);
+ DCHECK(!isMainThread());
+ RefPtr<WaitableEventWithTasks> eventWithTasks;
+ if (m_blockingBehavior == LoadSynchronously)
+ eventWithTasks = WaitableEventWithTasks::create();
- resourceLoaderOptions.requestInitiatorContext = WorkerContext;
- m_mainThreadLoader = DocumentThreadableLoader::create(*document, this, options, resourceLoaderOptions);
- ASSERT(m_mainThreadLoader);
-}
+ m_loaderProxy->postTaskToLoader(BLINK_FROM_HERE, createCrossThreadTask(
+ &Peer::createAndStart,
+ wrapCrossThreadPersistent(this),
+ m_loaderProxy,
+ wrapCrossThreadPersistent(workerGlobalScope.thread()->getWorkerThreadLifecycleContext()),
+ request,
+ m_threadableLoaderOptions,
+ m_resourceLoaderOptions,
+ eventWithTasks));
-void WorkerThreadableLoader::MainThreadBridgeBase::mainThreadStart(std::unique_ptr<CrossThreadResourceRequestData> requestData)
-{
- ASSERT(isMainThread());
- ASSERT(m_mainThreadLoader);
- m_mainThreadLoader->start(ResourceRequest(requestData.get()));
-}
+ if (m_blockingBehavior == LoadAsynchronously)
+ return;
-void WorkerThreadableLoader::MainThreadBridgeBase::createLoaderInMainThread(const ThreadableLoaderOptions& options, const ResourceLoaderOptions& resourceLoaderOptions)
-{
- m_loaderProxy->postTaskToLoader(BLINK_FROM_HERE, createCrossThreadTask(&MainThreadBridgeBase::mainThreadCreateLoader, crossThreadUnretained(this), options, resourceLoaderOptions));
-}
+ {
+ SafePointScope scope(BlinkGC::HeapPointersOnStack);
+ eventWithTasks->wait();
+ }
-void WorkerThreadableLoader::MainThreadBridgeBase::startInMainThread(const ResourceRequest& request, const WorkerGlobalScope& workerGlobalScope)
-{
- loaderProxy()->postTaskToLoader(BLINK_FROM_HERE, createCrossThreadTask(&MainThreadBridgeBase::mainThreadStart, crossThreadUnretained(this), request));
-}
+ if (eventWithTasks->isAborted()) {
+ // This thread is going to terminate.
+ cancel();
+ return;
+ }
-void WorkerThreadableLoader::MainThreadBridgeBase::mainThreadDestroy(ExecutionContext* context)
-{
- ASSERT(isMainThread());
- ASSERT_UNUSED(context, context->isDocument());
- delete this;
+ for (const auto& task : eventWithTasks->take()) {
+ // Store the program counter where the task is posted from, and alias
+ // it to ensure it is stored in the crash dump.
+ const void* programCounter = task.m_location.program_counter();
+ WTF::debug::alias(&programCounter);
+
+ // m_clientTask contains only CallClosureTasks. So, it's ok to pass
+ // the nullptr.
+ task.m_task->performTask(nullptr);
+ }
}
-void WorkerThreadableLoader::MainThreadBridgeBase::destroy()
+void WorkerThreadableLoader::Bridge::overrideTimeout(unsigned long timeoutMilliseconds)
{
- // Ensure that no more client callbacks are done in the worker context's
- // thread.
- // ThreadableLoaderClientWrapper is an on-heap class and this function can
- // be called in the finalization step but it is safe because
- // m_workerClientWrapper is a CrossThreadPersistent.
- m_workerClientWrapper->clearClient();
-
- // "delete this" and m_mainThreadLoader::deref() on the worker object's
- // thread.
- m_loaderProxy->postTaskToLoader(BLINK_FROM_HERE, createCrossThreadTask(&MainThreadBridgeBase::mainThreadDestroy, crossThreadUnretained(this)));
+ DCHECK(!isMainThread());
+ if (!m_peer)
+ return;
+ m_loaderProxy->postTaskToLoader(BLINK_FROM_HERE, createCrossThreadTask(&Peer::overrideTimeout, m_peer, timeoutMilliseconds));
}
-void WorkerThreadableLoader::MainThreadBridgeBase::mainThreadOverrideTimeout(unsigned long timeoutMilliseconds, ExecutionContext* context)
+void WorkerThreadableLoader::Bridge::cancel()
{
- ASSERT(isMainThread());
- ASSERT_UNUSED(context, context->isDocument());
+ DCHECK(!isMainThread());
+ cancelPeer();
- if (!m_mainThreadLoader)
+ if (m_clientWrapper->done())
return;
- m_mainThreadLoader->overrideTimeout(timeoutMilliseconds);
+ // If the client hasn't reached a termination state, then transition it
+ // by sending a cancellation error.
+ // Note: no more client callbacks will be done after this method -- the
+ // clearClient() call ensures that.
+ ResourceError error(String(), 0, String(), String());
+ error.setIsCancellation(true);
+ m_clientWrapper->didFail(error);
+ m_clientWrapper->clearClient();
}
-void WorkerThreadableLoader::MainThreadBridgeBase::overrideTimeout(unsigned long timeoutMilliseconds)
+void WorkerThreadableLoader::Bridge::destroy()
{
- m_loaderProxy->postTaskToLoader(BLINK_FROM_HERE, createCrossThreadTask(&MainThreadBridgeBase::mainThreadOverrideTimeout, crossThreadUnretained(this), timeoutMilliseconds));
+ DCHECK(!isMainThread());
+ cancelPeer();
+ m_clientWrapper->clearClient();
}
-void WorkerThreadableLoader::MainThreadBridgeBase::mainThreadCancel(ExecutionContext* context)
+void WorkerThreadableLoader::Bridge::didStart(Peer* peer)
{
- ASSERT(isMainThread());
- ASSERT_UNUSED(context, context->isDocument());
-
- if (!m_mainThreadLoader)
+ DCHECK(!isMainThread());
+ DCHECK(!m_peer);
+ DCHECK(peer);
+ if (m_clientWrapper->done()) {
+ // The loading is already cancelled.
return;
- m_mainThreadLoader->cancel();
- m_mainThreadLoader = nullptr;
-}
-
-void WorkerThreadableLoader::MainThreadBridgeBase::cancel()
-{
- m_loaderProxy->postTaskToLoader(BLINK_FROM_HERE, createCrossThreadTask(&MainThreadBridgeBase::mainThreadCancel, crossThreadUnretained(this)));
- ThreadableLoaderClientWrapper* clientWrapper = m_workerClientWrapper;
- if (!clientWrapper->done()) {
- // If the client hasn't reached a termination state, then transition it
- // by sending a cancellation error.
- // Note: no more client callbacks will be done after this method -- the
- // m_workerClientWrapper->clearClient() call ensures that.
- ResourceError error(String(), 0, String(), String());
- error.setIsCancellation(true);
- clientWrapper->didFail(error);
}
- // |this| might be already destructed here because didFail() might
- // clear a reference to ThreadableLoader, which might destruct
- // WorkerThreadableLoader and then MainThreadBridge.
- // Therefore we call clearClient() directly, rather than calling
- // this->m_workerClientWrapper->clearClient().
- clientWrapper->clearClient();
-}
-void WorkerThreadableLoader::MainThreadBridgeBase::didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent)
-{
- forwardTaskToWorker(BLINK_FROM_HERE, createCrossThreadTask(&ThreadableLoaderClientWrapper::didSendData, m_workerClientWrapper, bytesSent, totalBytesToBeSent));
+ m_peer = peer;
}
-void WorkerThreadableLoader::MainThreadBridgeBase::didReceiveResponse(unsigned long identifier, const ResourceResponse& response, std::unique_ptr<WebDataConsumerHandle> handle)
+DEFINE_TRACE(WorkerThreadableLoader::Bridge)
{
- forwardTaskToWorker(BLINK_FROM_HERE, createCrossThreadTask(&ThreadableLoaderClientWrapper::didReceiveResponse, m_workerClientWrapper, identifier, response, passed(std::move(handle))));
+ visitor->trace(m_clientWrapper);
}
-void WorkerThreadableLoader::MainThreadBridgeBase::didReceiveData(const char* data, unsigned dataLength)
+void WorkerThreadableLoader::Bridge::cancelPeer()
{
- forwardTaskToWorker(BLINK_FROM_HERE, createCrossThreadTask(&ThreadableLoaderClientWrapper::didReceiveData, m_workerClientWrapper, passed(createVectorFromMemoryRegion(data, dataLength))));
+ DCHECK(!isMainThread());
+ if (!m_peer)
+ return;
+ m_loaderProxy->postTaskToLoader(BLINK_FROM_HERE, createCrossThreadTask(&Peer::cancel, m_peer));
+ m_peer = nullptr;
}
-void WorkerThreadableLoader::MainThreadBridgeBase::didDownloadData(int dataLength)
-{
- forwardTaskToWorker(BLINK_FROM_HERE, createCrossThreadTask(&ThreadableLoaderClientWrapper::didDownloadData, m_workerClientWrapper, dataLength));
+void WorkerThreadableLoader::Peer::createAndStart(
+ Bridge* bridge,
+ PassRefPtr<WorkerLoaderProxy> passLoaderProxy,
+ WorkerThreadLifecycleContext* workerThreadLifecycleContext,
+ std::unique_ptr<CrossThreadResourceRequestData> request,
+ const ThreadableLoaderOptions& options,
+ const ResourceLoaderOptions& resourceLoaderOptions,
+ PassRefPtr<WaitableEventWithTasks> eventWithTasks,
+ ExecutionContext* executionContext)
+{
+ DCHECK(isMainThread());
+ TaskForwarder* forwarder;
+ RefPtr<WorkerLoaderProxy> loaderProxy = passLoaderProxy;
+ if (eventWithTasks)
+ forwarder = new SyncTaskForwarder(eventWithTasks);
+ else
+ forwarder = new AsyncTaskForwarder(loaderProxy);
+
+ Peer* peer = new Peer(forwarder, workerThreadLifecycleContext);
+ if (peer->wasContextDestroyedBeforeObserverCreation()) {
+ // The thread is already terminating.
+ forwarder->abort();
+ peer->m_forwarder = nullptr;
+ return;
+ }
+ peer->m_clientWrapper = bridge->clientWrapper();
+ peer->start(*toDocument(executionContext), std::move(request), options, resourceLoaderOptions);
+ forwarder->forwardTask(BLINK_FROM_HERE, createCrossThreadTask(&Bridge::didStart, wrapCrossThreadPersistent(bridge), wrapCrossThreadPersistent(peer)));
}
-void WorkerThreadableLoader::MainThreadBridgeBase::didReceiveCachedMetadata(const char* data, int dataLength)
+WorkerThreadableLoader::Peer::~Peer()
{
- forwardTaskToWorker(BLINK_FROM_HERE, createCrossThreadTask(&ThreadableLoaderClientWrapper::didReceiveCachedMetadata, m_workerClientWrapper, passed(createVectorFromMemoryRegion(data, dataLength))));
+ DCHECK(isMainThread());
+ DCHECK(!m_mainThreadLoader);
}
-void WorkerThreadableLoader::MainThreadBridgeBase::didFinishLoading(unsigned long identifier, double finishTime)
+void WorkerThreadableLoader::Peer::overrideTimeout(unsigned long timeoutMilliseconds)
{
- forwardTaskToWorkerOnLoaderDone(BLINK_FROM_HERE, createCrossThreadTask(&ThreadableLoaderClientWrapper::didFinishLoading, m_workerClientWrapper, identifier, finishTime));
+ DCHECK(isMainThread());
+ if (!m_mainThreadLoader)
+ return;
+ m_mainThreadLoader->overrideTimeout(timeoutMilliseconds);
}
-void WorkerThreadableLoader::MainThreadBridgeBase::didFail(const ResourceError& error)
+void WorkerThreadableLoader::Peer::cancel()
{
- forwardTaskToWorkerOnLoaderDone(BLINK_FROM_HERE, createCrossThreadTask(&ThreadableLoaderClientWrapper::didFail, m_workerClientWrapper, error));
+ DCHECK(isMainThread());
+ if (!m_mainThreadLoader)
+ return;
+ m_mainThreadLoader->cancel();
+ m_mainThreadLoader = nullptr;
}
-void WorkerThreadableLoader::MainThreadBridgeBase::didFailAccessControlCheck(const ResourceError& error)
+void WorkerThreadableLoader::Peer::didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent)
{
- forwardTaskToWorkerOnLoaderDone(BLINK_FROM_HERE, createCrossThreadTask(&ThreadableLoaderClientWrapper::didFailAccessControlCheck, m_workerClientWrapper, error));
+ DCHECK(isMainThread());
+ CrossThreadPersistent<ThreadableLoaderClientWrapper> clientWrapper = m_clientWrapper.get();
+ if (!clientWrapper || !m_forwarder)
+ return;
+ m_forwarder->forwardTask(BLINK_FROM_HERE, createCrossThreadTask(&ThreadableLoaderClientWrapper::didSendData, clientWrapper, bytesSent, totalBytesToBeSent));
}
-void WorkerThreadableLoader::MainThreadBridgeBase::didFailRedirectCheck()
+void WorkerThreadableLoader::Peer::didReceiveResponse(unsigned long identifier, const ResourceResponse& response, std::unique_ptr<WebDataConsumerHandle> handle)
{
- forwardTaskToWorkerOnLoaderDone(BLINK_FROM_HERE, createCrossThreadTask(&ThreadableLoaderClientWrapper::didFailRedirectCheck, m_workerClientWrapper));
+ DCHECK(isMainThread());
+ CrossThreadPersistent<ThreadableLoaderClientWrapper> clientWrapper = m_clientWrapper.get();
+ if (!clientWrapper || !m_forwarder)
+ return;
+ m_forwarder->forwardTask(BLINK_FROM_HERE, createCrossThreadTask(&ThreadableLoaderClientWrapper::didReceiveResponse, clientWrapper, identifier, response, passed(std::move(handle))));
}
-void WorkerThreadableLoader::MainThreadBridgeBase::didReceiveResourceTiming(const ResourceTimingInfo& info)
+void WorkerThreadableLoader::Peer::didReceiveData(const char* data, unsigned dataLength)
{
- forwardTaskToWorker(BLINK_FROM_HERE, createCrossThreadTask(&ThreadableLoaderClientWrapper::didReceiveResourceTiming, m_workerClientWrapper, info));
+ DCHECK(isMainThread());
+ CrossThreadPersistent<ThreadableLoaderClientWrapper> clientWrapper = m_clientWrapper.get();
+ if (!clientWrapper || !m_forwarder)
+ return;
+ m_forwarder->forwardTask(BLINK_FROM_HERE, createCrossThreadTask(&ThreadableLoaderClientWrapper::didReceiveData, clientWrapper, passed(createVectorFromMemoryRegion(data, dataLength))));
}
-WorkerThreadableLoader::MainThreadAsyncBridge::MainThreadAsyncBridge(
- WorkerGlobalScope& workerGlobalScope,
- ThreadableLoaderClientWrapper* workerClientWrapper,
- const ThreadableLoaderOptions& options,
- const ResourceLoaderOptions& resourceLoaderOptions)
- : MainThreadBridgeBase(workerClientWrapper, workerGlobalScope.thread()->workerLoaderProxy())
+void WorkerThreadableLoader::Peer::didDownloadData(int dataLength)
{
- createLoaderInMainThread(options, resourceLoaderOptions);
+ DCHECK(isMainThread());
+ CrossThreadPersistent<ThreadableLoaderClientWrapper> clientWrapper = m_clientWrapper.get();
+ if (!clientWrapper || !m_forwarder)
+ return;
+ m_forwarder->forwardTask(BLINK_FROM_HERE, createCrossThreadTask(&ThreadableLoaderClientWrapper::didDownloadData, clientWrapper, dataLength));
}
-void WorkerThreadableLoader::MainThreadAsyncBridge::start(const ResourceRequest& request, const WorkerGlobalScope& workerGlobalScope)
+void WorkerThreadableLoader::Peer::didReceiveCachedMetadata(const char* data, int dataLength)
{
- startInMainThread(request, workerGlobalScope);
+ DCHECK(isMainThread());
+ CrossThreadPersistent<ThreadableLoaderClientWrapper> clientWrapper = m_clientWrapper.get();
+ if (!clientWrapper || !m_forwarder)
+ return;
+ m_forwarder->forwardTask(BLINK_FROM_HERE, createCrossThreadTask(&ThreadableLoaderClientWrapper::didReceiveCachedMetadata, clientWrapper, passed(createVectorFromMemoryRegion(data, dataLength))));
}
-WorkerThreadableLoader::MainThreadAsyncBridge::~MainThreadAsyncBridge()
+void WorkerThreadableLoader::Peer::didFinishLoading(unsigned long identifier, double finishTime)
{
+ DCHECK(isMainThread());
+ CrossThreadPersistent<ThreadableLoaderClientWrapper> clientWrapper = m_clientWrapper.get();
+ if (!clientWrapper || !m_forwarder)
+ return;
+ m_forwarder->forwardTaskWithDoneSignal(BLINK_FROM_HERE, createCrossThreadTask(&ThreadableLoaderClientWrapper::didFinishLoading, clientWrapper, identifier, finishTime));
+ m_forwarder = nullptr;
}
-void WorkerThreadableLoader::MainThreadAsyncBridge::forwardTaskToWorker(const WebTraceLocation& location, std::unique_ptr<ExecutionContextTask> task)
+void WorkerThreadableLoader::Peer::didFail(const ResourceError& error)
{
- loaderProxy()->postTaskToWorkerGlobalScope(location, std::move(task));
+ DCHECK(isMainThread());
+ CrossThreadPersistent<ThreadableLoaderClientWrapper> clientWrapper = m_clientWrapper.get();
+ if (!clientWrapper || !m_forwarder)
+ return;
+ m_forwarder->forwardTaskWithDoneSignal(BLINK_FROM_HERE, createCrossThreadTask(&ThreadableLoaderClientWrapper::didFail, clientWrapper, error));
+ m_forwarder = nullptr;
}
-void WorkerThreadableLoader::MainThreadAsyncBridge::forwardTaskToWorkerOnLoaderDone(const WebTraceLocation& location, std::unique_ptr<ExecutionContextTask> task)
+void WorkerThreadableLoader::Peer::didFailAccessControlCheck(const ResourceError& error)
{
- loaderProxy()->postTaskToWorkerGlobalScope(location, std::move(task));
+ DCHECK(isMainThread());
+ CrossThreadPersistent<ThreadableLoaderClientWrapper> clientWrapper = m_clientWrapper.get();
+ if (!clientWrapper || !m_forwarder)
+ return;
+ m_forwarder->forwardTaskWithDoneSignal(BLINK_FROM_HERE, createCrossThreadTask(&ThreadableLoaderClientWrapper::didFailAccessControlCheck, clientWrapper, error));
+ m_forwarder = nullptr;
}
-WorkerThreadableLoader::MainThreadSyncBridge::MainThreadSyncBridge(
- WorkerGlobalScope& workerGlobalScope,
- ThreadableLoaderClientWrapper* workerClientWrapper,
- const ThreadableLoaderOptions& options,
- const ResourceLoaderOptions& resourceLoaderOptions)
- : MainThreadBridgeBase(workerClientWrapper, workerGlobalScope.thread()->workerLoaderProxy())
- , m_done(false)
+void WorkerThreadableLoader::Peer::didFailRedirectCheck()
{
- createLoaderInMainThread(options, resourceLoaderOptions);
+ DCHECK(isMainThread());
+ CrossThreadPersistent<ThreadableLoaderClientWrapper> clientWrapper = m_clientWrapper.get();
+ if (!clientWrapper || !m_forwarder)
+ return;
+ m_forwarder->forwardTaskWithDoneSignal(BLINK_FROM_HERE, createCrossThreadTask(&ThreadableLoaderClientWrapper::didFailRedirectCheck, clientWrapper));
+ m_forwarder = nullptr;
}
-void WorkerThreadableLoader::MainThreadSyncBridge::start(const ResourceRequest& request, const WorkerGlobalScope& workerGlobalScope)
+void WorkerThreadableLoader::Peer::didReceiveResourceTiming(const ResourceTimingInfo& info)
{
- WaitableEvent* terminationEvent = workerGlobalScope.thread()->terminationEvent();
- m_loaderDoneEvent = wrapUnique(new WaitableEvent());
-
- startInMainThread(request, workerGlobalScope);
-
- size_t signaledIndex;
- {
- Vector<WaitableEvent*> events;
- // Order is important; indicies are used later.
- events.append(terminationEvent);
- events.append(m_loaderDoneEvent.get());
-
- SafePointScope scope(BlinkGC::HeapPointersOnStack);
- signaledIndex = WaitableEvent::waitMultiple(events);
- }
- // |signaledIndex| is 0; which is terminationEvent.
- if (signaledIndex == 0) {
- cancel();
+ DCHECK(isMainThread());
+ CrossThreadPersistent<ThreadableLoaderClientWrapper> clientWrapper = m_clientWrapper.get();
+ if (!clientWrapper || !m_forwarder)
return;
- }
-
- // The following code must be run only after |m_loaderDoneEvent| is
- // signalled.
-
- Vector<ClientTask> tasks;
- {
- MutexLocker lock(m_lock);
- ASSERT(m_done);
- m_clientTasks.swap(tasks);
- }
- for (const auto& task : tasks) {
- // Store the program counter where the task is posted from, and alias
- // it to ensure it is stored in the crash dump.
- const void* programCounter = task.m_location.program_counter();
- WTF::debug::alias(&programCounter);
+ m_forwarder->forwardTask(BLINK_FROM_HERE, createCrossThreadTask(&ThreadableLoaderClientWrapper::didReceiveResourceTiming, clientWrapper, info));
+}
- // m_clientTask contains only CallClosureTasks. So, it's ok to pass
- // the nullptr.
- task.m_task->performTask(nullptr);
+void WorkerThreadableLoader::Peer::contextDestroyed()
+{
+ DCHECK(isMainThread());
+ if (m_forwarder) {
+ m_forwarder->abort();
+ m_forwarder = nullptr;
}
+ m_clientWrapper = nullptr;
+ cancel();
}
-WorkerThreadableLoader::MainThreadSyncBridge::ClientTask::ClientTask(const WebTraceLocation& location, std::unique_ptr<ExecutionContextTask> task)
- : m_location(location)
- , m_task(std::move(task)) {}
-
-WorkerThreadableLoader::MainThreadSyncBridge::ClientTask::~ClientTask() = default;
-WorkerThreadableLoader::MainThreadSyncBridge::ClientTask::ClientTask(ClientTask&&) = default;
-
-WorkerThreadableLoader::MainThreadSyncBridge::~MainThreadSyncBridge()
+DEFINE_TRACE(WorkerThreadableLoader::Peer)
{
- ASSERT(isMainThread());
+ visitor->trace(m_forwarder);
+ WorkerThreadLifecycleObserver::trace(visitor);
}
-void WorkerThreadableLoader::MainThreadSyncBridge::forwardTaskToWorker(const WebTraceLocation& location, std::unique_ptr<ExecutionContextTask> task)
+WorkerThreadableLoader::Peer::Peer(TaskForwarder* forwarder, WorkerThreadLifecycleContext* context)
+ : WorkerThreadLifecycleObserver(context)
+ , m_forwarder(forwarder)
{
- ASSERT(isMainThread());
-
- MutexLocker lock(m_lock);
- RELEASE_ASSERT(!m_done);
-
- m_clientTasks.append(ClientTask(location, std::move(task)));
+ DCHECK(isMainThread());
}
-void WorkerThreadableLoader::MainThreadSyncBridge::forwardTaskToWorkerOnLoaderDone(const WebTraceLocation& location, std::unique_ptr<ExecutionContextTask> task)
+void WorkerThreadableLoader::Peer::start(
+ Document& document,
+ std::unique_ptr<CrossThreadResourceRequestData> request,
+ const ThreadableLoaderOptions& options,
+ const ResourceLoaderOptions& originalResourceLoaderOptions)
{
- ASSERT(isMainThread());
-
- MutexLocker lock(m_lock);
- RELEASE_ASSERT(!m_done);
-
- m_clientTasks.append(ClientTask(location, std::move(task)));
- m_done = true;
- m_loaderDoneEvent->signal();
+ DCHECK(isMainThread());
+ ResourceLoaderOptions resourceLoaderOptions = originalResourceLoaderOptions;
+ resourceLoaderOptions.requestInitiatorContext = WorkerContext;
+ m_mainThreadLoader = DocumentThreadableLoader::create(document, this, options, resourceLoaderOptions);
+ m_mainThreadLoader->start(ResourceRequest(request.get()));
}
} // namespace blink
« no previous file with comments | « third_party/WebKit/Source/core/loader/WorkerThreadableLoader.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698