| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2009, 2010 Google Inc. All rights reserved. | 2 * Copyright (C) 2009, 2010 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 54 | 54 |
| 55 static std::unique_ptr<Vector<char>> createVectorFromMemoryRegion(const char* da
ta, unsigned dataLength) | 55 static std::unique_ptr<Vector<char>> createVectorFromMemoryRegion(const char* da
ta, unsigned dataLength) |
| 56 { | 56 { |
| 57 std::unique_ptr<Vector<char>> buffer = wrapUnique(new Vector<char>(dataLengt
h)); | 57 std::unique_ptr<Vector<char>> buffer = wrapUnique(new Vector<char>(dataLengt
h)); |
| 58 memcpy(buffer->data(), data, dataLength); | 58 memcpy(buffer->data(), data, dataLength); |
| 59 return buffer; | 59 return buffer; |
| 60 } | 60 } |
| 61 | 61 |
| 62 WorkerThreadableLoader::WorkerThreadableLoader(WorkerGlobalScope& workerGlobalSc
ope, ThreadableLoaderClient* client, const ThreadableLoaderOptions& options, con
st ResourceLoaderOptions& resourceLoaderOptions, BlockingBehavior blockingBehavi
or) | 62 WorkerThreadableLoader::WorkerThreadableLoader(WorkerGlobalScope& workerGlobalSc
ope, ThreadableLoaderClient* client, const ThreadableLoaderOptions& options, con
st ResourceLoaderOptions& resourceLoaderOptions, BlockingBehavior blockingBehavi
or) |
| 63 : m_workerGlobalScope(&workerGlobalScope) | 63 : m_workerGlobalScope(&workerGlobalScope) |
| 64 , m_workerClientWrapper(ThreadableLoaderClientWrapper::create(client)) | 64 , m_workerClientWrapper(new ThreadableLoaderClientWrapper(workerGlobalScope,
client)) |
| 65 { | 65 { |
| 66 m_workerClientWrapper->setResourceTimingClient(this); | |
| 67 if (blockingBehavior == LoadAsynchronously) { | 66 if (blockingBehavior == LoadAsynchronously) { |
| 68 m_bridge = new MainThreadAsyncBridge(workerGlobalScope, m_workerClientWr
apper, options, resourceLoaderOptions); | 67 m_bridge = new MainThreadAsyncBridge(workerGlobalScope, m_workerClientWr
apper, options, resourceLoaderOptions); |
| 69 } else { | 68 } else { |
| 70 m_bridge = new MainThreadSyncBridge(workerGlobalScope, m_workerClientWra
pper, options, resourceLoaderOptions); | 69 m_bridge = new MainThreadSyncBridge(workerGlobalScope, m_workerClientWra
pper, options, resourceLoaderOptions); |
| 71 } | 70 } |
| 72 } | 71 } |
| 73 | 72 |
| 74 void WorkerThreadableLoader::loadResourceSynchronously(WorkerGlobalScope& worker
GlobalScope, const ResourceRequest& request, ThreadableLoaderClient& client, con
st ThreadableLoaderOptions& options, const ResourceLoaderOptions& resourceLoader
Options) | 73 void WorkerThreadableLoader::loadResourceSynchronously(WorkerGlobalScope& worker
GlobalScope, const ResourceRequest& request, ThreadableLoaderClient& client, con
st ThreadableLoaderOptions& options, const ResourceLoaderOptions& resourceLoader
Options) |
| 75 { | 74 { |
| 76 std::unique_ptr<WorkerThreadableLoader> loader = wrapUnique(new WorkerThread
ableLoader(workerGlobalScope, &client, options, resourceLoaderOptions, LoadSynch
ronously)); | 75 std::unique_ptr<WorkerThreadableLoader> loader = wrapUnique(new WorkerThread
ableLoader(workerGlobalScope, &client, options, resourceLoaderOptions, LoadSynch
ronously)); |
| 77 loader->start(request); | 76 loader->start(request); |
| 78 } | 77 } |
| 79 | 78 |
| 80 WorkerThreadableLoader::~WorkerThreadableLoader() | 79 WorkerThreadableLoader::~WorkerThreadableLoader() |
| 81 { | 80 { |
| 82 m_workerClientWrapper->clearResourceTimingClient(); | |
| 83 m_bridge->destroy(); | 81 m_bridge->destroy(); |
| 84 m_bridge = nullptr; | 82 m_bridge = nullptr; |
| 85 } | 83 } |
| 86 | 84 |
| 87 void WorkerThreadableLoader::start(const ResourceRequest& request) | 85 void WorkerThreadableLoader::start(const ResourceRequest& request) |
| 88 { | 86 { |
| 89 ResourceRequest requestToPass(request); | 87 ResourceRequest requestToPass(request); |
| 90 if (!requestToPass.didSetHTTPReferrer()) | 88 if (!requestToPass.didSetHTTPReferrer()) |
| 91 requestToPass.setHTTPReferrer(SecurityPolicy::generateReferrer(m_workerG
lobalScope->getReferrerPolicy(), request.url(), m_workerGlobalScope->outgoingRef
errer())); | 89 requestToPass.setHTTPReferrer(SecurityPolicy::generateReferrer(m_workerG
lobalScope->getReferrerPolicy(), request.url(), m_workerGlobalScope->outgoingRef
errer())); |
| 92 m_bridge->start(requestToPass, *m_workerGlobalScope); | 90 m_bridge->start(requestToPass, *m_workerGlobalScope); |
| 93 m_workerClientWrapper->setResourceTimingClient(this); | |
| 94 } | 91 } |
| 95 | 92 |
| 96 void WorkerThreadableLoader::overrideTimeout(unsigned long timeoutMilliseconds) | 93 void WorkerThreadableLoader::overrideTimeout(unsigned long timeoutMilliseconds) |
| 97 { | 94 { |
| 98 ASSERT(m_bridge); | 95 ASSERT(m_bridge); |
| 99 m_bridge->overrideTimeout(timeoutMilliseconds); | 96 m_bridge->overrideTimeout(timeoutMilliseconds); |
| 100 } | 97 } |
| 101 | 98 |
| 102 void WorkerThreadableLoader::cancel() | 99 void WorkerThreadableLoader::cancel() |
| 103 { | 100 { |
| 104 ASSERT(m_bridge); | 101 ASSERT(m_bridge); |
| 105 m_bridge->cancel(); | 102 m_bridge->cancel(); |
| 106 } | 103 } |
| 107 | 104 |
| 108 void WorkerThreadableLoader::didReceiveResourceTiming(const ResourceTimingInfo&
info) | |
| 109 { | |
| 110 WorkerGlobalScopePerformance::performance(*m_workerGlobalScope)->addResource
Timing(info); | |
| 111 } | |
| 112 | |
| 113 WorkerThreadableLoader::MainThreadBridgeBase::MainThreadBridgeBase( | 105 WorkerThreadableLoader::MainThreadBridgeBase::MainThreadBridgeBase( |
| 114 PassRefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, | 106 ThreadableLoaderClientWrapper* workerClientWrapper, |
| 115 PassRefPtr<WorkerLoaderProxy> loaderProxy) | 107 PassRefPtr<WorkerLoaderProxy> loaderProxy) |
| 116 : m_workerClientWrapper(workerClientWrapper) | 108 : m_workerClientWrapper(workerClientWrapper) |
| 117 , m_loaderProxy(loaderProxy) | 109 , m_loaderProxy(loaderProxy) |
| 118 { | 110 { |
| 119 ASSERT(m_workerClientWrapper.get()); | 111 ASSERT(m_workerClientWrapper.get()); |
| 120 ASSERT(m_loaderProxy.get()); | 112 ASSERT(m_loaderProxy.get()); |
| 121 } | 113 } |
| 122 | 114 |
| 123 WorkerThreadableLoader::MainThreadBridgeBase::~MainThreadBridgeBase() | 115 WorkerThreadableLoader::MainThreadBridgeBase::~MainThreadBridgeBase() |
| 124 { | 116 { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 153 | 145 |
| 154 void WorkerThreadableLoader::MainThreadBridgeBase::mainThreadDestroy(ExecutionCo
ntext* context) | 146 void WorkerThreadableLoader::MainThreadBridgeBase::mainThreadDestroy(ExecutionCo
ntext* context) |
| 155 { | 147 { |
| 156 ASSERT(isMainThread()); | 148 ASSERT(isMainThread()); |
| 157 ASSERT_UNUSED(context, context->isDocument()); | 149 ASSERT_UNUSED(context, context->isDocument()); |
| 158 delete this; | 150 delete this; |
| 159 } | 151 } |
| 160 | 152 |
| 161 void WorkerThreadableLoader::MainThreadBridgeBase::destroy() | 153 void WorkerThreadableLoader::MainThreadBridgeBase::destroy() |
| 162 { | 154 { |
| 163 // Ensure that no more client callbacks are done in the worker context's thr
ead. | 155 // Ensure that no more client callbacks are done in the worker context's |
| 156 // thread. |
| 157 // ThreadableLoaderClientWrapper is an on-heap class and this function can |
| 158 // be called in the finalization step but it is safe because |
| 159 // m_workerClientWrapper is a CrossThreadPersistent. |
| 164 m_workerClientWrapper->clearClient(); | 160 m_workerClientWrapper->clearClient(); |
| 165 | 161 |
| 166 // "delete this" and m_mainThreadLoader::deref() on the worker object's thre
ad. | 162 // "delete this" and m_mainThreadLoader::deref() on the worker object's |
| 163 // thread. |
| 167 m_loaderProxy->postTaskToLoader(createCrossThreadTask(&MainThreadBridgeBase:
:mainThreadDestroy, crossThreadUnretained(this))); | 164 m_loaderProxy->postTaskToLoader(createCrossThreadTask(&MainThreadBridgeBase:
:mainThreadDestroy, crossThreadUnretained(this))); |
| 168 } | 165 } |
| 169 | 166 |
| 170 void WorkerThreadableLoader::MainThreadBridgeBase::mainThreadOverrideTimeout(uns
igned long timeoutMilliseconds, ExecutionContext* context) | 167 void WorkerThreadableLoader::MainThreadBridgeBase::mainThreadOverrideTimeout(uns
igned long timeoutMilliseconds, ExecutionContext* context) |
| 171 { | 168 { |
| 172 ASSERT(isMainThread()); | 169 ASSERT(isMainThread()); |
| 173 ASSERT_UNUSED(context, context->isDocument()); | 170 ASSERT_UNUSED(context, context->isDocument()); |
| 174 | 171 |
| 175 if (!m_mainThreadLoader) | 172 if (!m_mainThreadLoader) |
| 176 return; | 173 return; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 189 | 186 |
| 190 if (!m_mainThreadLoader) | 187 if (!m_mainThreadLoader) |
| 191 return; | 188 return; |
| 192 m_mainThreadLoader->cancel(); | 189 m_mainThreadLoader->cancel(); |
| 193 m_mainThreadLoader = nullptr; | 190 m_mainThreadLoader = nullptr; |
| 194 } | 191 } |
| 195 | 192 |
| 196 void WorkerThreadableLoader::MainThreadBridgeBase::cancel() | 193 void WorkerThreadableLoader::MainThreadBridgeBase::cancel() |
| 197 { | 194 { |
| 198 m_loaderProxy->postTaskToLoader(createCrossThreadTask(&MainThreadBridgeBase:
:mainThreadCancel, crossThreadUnretained(this))); | 195 m_loaderProxy->postTaskToLoader(createCrossThreadTask(&MainThreadBridgeBase:
:mainThreadCancel, crossThreadUnretained(this))); |
| 199 RefPtr<ThreadableLoaderClientWrapper> clientWrapper = m_workerClientWrapper; | 196 ThreadableLoaderClientWrapper* clientWrapper = m_workerClientWrapper; |
| 200 if (!clientWrapper->done()) { | 197 if (!clientWrapper->done()) { |
| 201 // If the client hasn't reached a termination state, then transition it
by sending a cancellation error. | 198 // If the client hasn't reached a termination state, then transition it |
| 202 // Note: no more client callbacks will be done after this method -- the
m_workerClientWrapper->clearClient() call ensures that. | 199 // by sending a cancellation error. |
| 200 // Note: no more client callbacks will be done after this method -- the |
| 201 // m_workerClientWrapper->clearClient() call ensures that. |
| 203 ResourceError error(String(), 0, String(), String()); | 202 ResourceError error(String(), 0, String(), String()); |
| 204 error.setIsCancellation(true); | 203 error.setIsCancellation(true); |
| 205 clientWrapper->didFail(error); | 204 clientWrapper->didFail(error); |
| 206 } | 205 } |
| 207 // |this| might be already destructed here because didFail() might | 206 // |this| might be already destructed here because didFail() might |
| 208 // clear a reference to ThreadableLoader, which might destruct | 207 // clear a reference to ThreadableLoader, which might destruct |
| 209 // WorkerThreadableLoader and then MainThreadBridge. | 208 // WorkerThreadableLoader and then MainThreadBridge. |
| 210 // Therefore we call clearClient() directly, rather than calling | 209 // Therefore we call clearClient() directly, rather than calling |
| 211 // this->m_workerClientWrapper->clearClient(). | 210 // this->m_workerClientWrapper->clearClient(). |
| 212 clientWrapper->clearClient(); | 211 clientWrapper->clearClient(); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 257 forwardTaskToWorkerOnLoaderDone(createCrossThreadTask(&ThreadableLoaderClien
tWrapper::didFailRedirectCheck, m_workerClientWrapper)); | 256 forwardTaskToWorkerOnLoaderDone(createCrossThreadTask(&ThreadableLoaderClien
tWrapper::didFailRedirectCheck, m_workerClientWrapper)); |
| 258 } | 257 } |
| 259 | 258 |
| 260 void WorkerThreadableLoader::MainThreadBridgeBase::didReceiveResourceTiming(cons
t ResourceTimingInfo& info) | 259 void WorkerThreadableLoader::MainThreadBridgeBase::didReceiveResourceTiming(cons
t ResourceTimingInfo& info) |
| 261 { | 260 { |
| 262 forwardTaskToWorker(createCrossThreadTask(&ThreadableLoaderClientWrapper::di
dReceiveResourceTiming, m_workerClientWrapper, info)); | 261 forwardTaskToWorker(createCrossThreadTask(&ThreadableLoaderClientWrapper::di
dReceiveResourceTiming, m_workerClientWrapper, info)); |
| 263 } | 262 } |
| 264 | 263 |
| 265 WorkerThreadableLoader::MainThreadAsyncBridge::MainThreadAsyncBridge( | 264 WorkerThreadableLoader::MainThreadAsyncBridge::MainThreadAsyncBridge( |
| 266 WorkerGlobalScope& workerGlobalScope, | 265 WorkerGlobalScope& workerGlobalScope, |
| 267 PassRefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, | 266 ThreadableLoaderClientWrapper* workerClientWrapper, |
| 268 const ThreadableLoaderOptions& options, | 267 const ThreadableLoaderOptions& options, |
| 269 const ResourceLoaderOptions& resourceLoaderOptions) | 268 const ResourceLoaderOptions& resourceLoaderOptions) |
| 270 : MainThreadBridgeBase(workerClientWrapper, workerGlobalScope.thread()->work
erLoaderProxy()) | 269 : MainThreadBridgeBase(workerClientWrapper, workerGlobalScope.thread()->work
erLoaderProxy()) |
| 271 { | 270 { |
| 272 createLoaderInMainThread(options, resourceLoaderOptions); | 271 createLoaderInMainThread(options, resourceLoaderOptions); |
| 273 } | 272 } |
| 274 | 273 |
| 275 void WorkerThreadableLoader::MainThreadAsyncBridge::start(const ResourceRequest&
request, const WorkerGlobalScope& workerGlobalScope) | 274 void WorkerThreadableLoader::MainThreadAsyncBridge::start(const ResourceRequest&
request, const WorkerGlobalScope& workerGlobalScope) |
| 276 { | 275 { |
| 277 startInMainThread(request, workerGlobalScope); | 276 startInMainThread(request, workerGlobalScope); |
| 278 } | 277 } |
| 279 | 278 |
| 280 WorkerThreadableLoader::MainThreadAsyncBridge::~MainThreadAsyncBridge() | 279 WorkerThreadableLoader::MainThreadAsyncBridge::~MainThreadAsyncBridge() |
| 281 { | 280 { |
| 282 } | 281 } |
| 283 | 282 |
| 284 void WorkerThreadableLoader::MainThreadAsyncBridge::forwardTaskToWorker(std::uni
que_ptr<ExecutionContextTask> task) | 283 void WorkerThreadableLoader::MainThreadAsyncBridge::forwardTaskToWorker(std::uni
que_ptr<ExecutionContextTask> task) |
| 285 { | 284 { |
| 286 loaderProxy()->postTaskToWorkerGlobalScope(std::move(task)); | 285 loaderProxy()->postTaskToWorkerGlobalScope(std::move(task)); |
| 287 } | 286 } |
| 288 | 287 |
| 289 void WorkerThreadableLoader::MainThreadAsyncBridge::forwardTaskToWorkerOnLoaderD
one(std::unique_ptr<ExecutionContextTask> task) | 288 void WorkerThreadableLoader::MainThreadAsyncBridge::forwardTaskToWorkerOnLoaderD
one(std::unique_ptr<ExecutionContextTask> task) |
| 290 { | 289 { |
| 291 loaderProxy()->postTaskToWorkerGlobalScope(std::move(task)); | 290 loaderProxy()->postTaskToWorkerGlobalScope(std::move(task)); |
| 292 } | 291 } |
| 293 | 292 |
| 294 WorkerThreadableLoader::MainThreadSyncBridge::MainThreadSyncBridge( | 293 WorkerThreadableLoader::MainThreadSyncBridge::MainThreadSyncBridge( |
| 295 WorkerGlobalScope& workerGlobalScope, | 294 WorkerGlobalScope& workerGlobalScope, |
| 296 PassRefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, | 295 ThreadableLoaderClientWrapper* workerClientWrapper, |
| 297 const ThreadableLoaderOptions& options, | 296 const ThreadableLoaderOptions& options, |
| 298 const ResourceLoaderOptions& resourceLoaderOptions) | 297 const ResourceLoaderOptions& resourceLoaderOptions) |
| 299 : MainThreadBridgeBase(workerClientWrapper, workerGlobalScope.thread()->work
erLoaderProxy()) | 298 : MainThreadBridgeBase(workerClientWrapper, workerGlobalScope.thread()->work
erLoaderProxy()) |
| 300 , m_done(false) | 299 , m_done(false) |
| 301 { | 300 { |
| 302 createLoaderInMainThread(options, resourceLoaderOptions); | 301 createLoaderInMainThread(options, resourceLoaderOptions); |
| 303 } | 302 } |
| 304 | 303 |
| 305 void WorkerThreadableLoader::MainThreadSyncBridge::start(const ResourceRequest&
request, const WorkerGlobalScope& workerGlobalScope) | 304 void WorkerThreadableLoader::MainThreadSyncBridge::start(const ResourceRequest&
request, const WorkerGlobalScope& workerGlobalScope) |
| 306 { | 305 { |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 362 | 361 |
| 363 MutexLocker lock(m_lock); | 362 MutexLocker lock(m_lock); |
| 364 RELEASE_ASSERT(!m_done); | 363 RELEASE_ASSERT(!m_done); |
| 365 | 364 |
| 366 m_clientTasks.append(std::move(task)); | 365 m_clientTasks.append(std::move(task)); |
| 367 m_done = true; | 366 m_done = true; |
| 368 m_loaderDoneEvent->signal(); | 367 m_loaderDoneEvent->signal(); |
| 369 } | 368 } |
| 370 | 369 |
| 371 } // namespace blink | 370 } // namespace blink |
| OLD | NEW |