15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2010 Google Inc. All rights reserved. 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions are 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * met: 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Redistributions of source code must retain the above copyright 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer. 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Redistributions in binary form must reproduce the above 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * copyright notice, this list of conditions and the following disclaimer 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * in the documentation and/or other materials provided with the 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * distribution. 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Neither the name of Google Inc. nor the names of its 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * contributors may be used to endorse or promote products derived from 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * this software without specific prior written permission. 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/fileapi/FileReader.h" 3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 34197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/ExceptionState.h" 3553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/CrossThreadTask.h" 36197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "core/dom/Document.h" 3753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/ExceptionCode.h" 381e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "core/dom/ExecutionContext.h" 3906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)#include "core/events/ProgressEvent.h" 4053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/fileapi/File.h" 41197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "core/frame/LocalFrame.h" 42c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "core/inspector/InspectorInstrumentation.h" 43197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "core/workers/WorkerClients.h" 44197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "core/workers/WorkerGlobalScope.h" 451e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/Logging.h" 46197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "platform/Supplementable.h" 47e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch#include "wtf/ArrayBuffer.h" 48e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch#include "wtf/CurrentTime.h" 49a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "wtf/Deque.h" 50a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "wtf/HashSet.h" 51e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch#include "wtf/text/CString.h" 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 53c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink { 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)namespace { 5693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 5751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#if !LOG_DISABLED 581e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)const CString utf8BlobUUID(Blob* blob) 5993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){ 601e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) return blob->uuid().utf8(); 6193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)} 6293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 6393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)const CString utf8FilePath(Blob* blob) 6493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){ 6551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) return blob->hasBackingFile() ? toFile(blob)->path().utf8() : ""; 6693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)} 6751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#endif 6893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 6993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)} // namespace 7093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 71a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)// Embedders like chromium limit the number of simultaneous requests to avoid 72a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)// excessive IPC congestion. We limit this to 100 per thread to throttle the 73a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)// requests (the value is arbitrarily chosen). 74a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)static const size_t kMaxOutstandingRequestsPerThread = 100; 755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static const double progressNotificationIntervalMS = 50; 765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 77197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch// FIXME: Oilpan: if ExecutionContext is moved to the heap, consider 78197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch// making this object an ExecutionContext supplement (only.) 79197021e6b966cfb06891637935ef33fff06433d1Ben Murdochclass FileReader::ThrottlingController FINAL : public NoBaseWillBeGarbageCollectedFinalized<FileReader::ThrottlingController>, public WillBeHeapSupplement<LocalFrame>, public WillBeHeapSupplement<WorkerClients> { 80197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(FileReader::ThrottlingController); 81a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)public: 82197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch static ThrottlingController* from(ExecutionContext* context) 83197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch { 84197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (!context) 85197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return 0; 86197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 87197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (context->isDocument()) { 88197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch Document* document = toDocument(context); 89197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (!document->frame()) 90197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return 0; 91197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 92197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch ThrottlingController* controller = static_cast<ThrottlingController*>(WillBeHeapSupplement<LocalFrame>::from(document->frame(), supplementName())); 93197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (controller) 94197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return controller; 95197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 96197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch controller = new ThrottlingController(); 97197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch WillBeHeapSupplement<LocalFrame>::provideTo(*document->frame(), supplementName(), adoptPtrWillBeNoop(controller)); 98197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return controller; 99197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch } 100197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch ASSERT(!isMainThread()); 101197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch ASSERT(context->isWorkerGlobalScope()); 102197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(context); 103197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch ThrottlingController* controller = static_cast<ThrottlingController*>(WillBeHeapSupplement<WorkerClients>::from(workerGlobalScope->clients(), supplementName())); 104197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (controller) 105197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return controller; 106197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 107197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch controller = new ThrottlingController(); 108197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch WillBeHeapSupplement<WorkerClients>::provideTo(*workerGlobalScope->clients(), supplementName(), adoptPtrWillBeNoop(controller)); 109197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return controller; 110197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch } 111197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 112a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) ~ThrottlingController() { } 113a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) 114d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) enum FinishReaderType { DoNotRunPendingReaders, RunPendingReaders }; 115d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 116197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch static void pushReader(ExecutionContext* context, FileReader* reader) 117197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch { 118197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch ThrottlingController* controller = from(context); 119197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (!controller) 120197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return; 121197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 122c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) reader->m_asyncOperationId = InspectorInstrumentation::traceAsyncOperationStarting(context, "FileReader"); 123197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch controller->pushReader(reader); 124197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch } 125197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 126197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch static FinishReaderType removeReader(ExecutionContext* context, FileReader* reader) 127197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch { 128197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch ThrottlingController* controller = from(context); 129197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (!controller) 130197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return DoNotRunPendingReaders; 131197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 132197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return controller->removeReader(reader); 133197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch } 134197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 135197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch static void finishReader(ExecutionContext* context, FileReader* reader, FinishReaderType nextStep) 136197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch { 137c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) InspectorInstrumentation::traceAsyncOperationCompleted(context, reader->m_asyncOperationId); 138c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 139197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch ThrottlingController* controller = from(context); 140197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (!controller) 141197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return; 142197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 143197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch controller->finishReader(reader, nextStep); 144197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch } 145197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 146197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch void trace(Visitor* visitor) 147197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch { 148197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(OILPAN) 149197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch visitor->trace(m_pendingReaders); 150197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch visitor->trace(m_runningReaders); 151197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#endif 152197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch WillBeHeapSupplement<LocalFrame>::trace(visitor); 153197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch WillBeHeapSupplement<WorkerClients>::trace(visitor); 154197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch } 155197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 156197021e6b966cfb06891637935ef33fff06433d1Ben Murdochprivate: 157197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch ThrottlingController() 158197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch : m_maxRunningReaders(kMaxOutstandingRequestsPerThread) 159197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch { 160197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch } 161197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 162a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) void pushReader(FileReader* reader) 163a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) { 164a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) if (m_pendingReaders.isEmpty() 165a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) && m_runningReaders.size() < m_maxRunningReaders) { 166a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) reader->executePendingRead(); 167d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) ASSERT(!m_runningReaders.contains(reader)); 168a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) m_runningReaders.add(reader); 169a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) return; 170a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) } 171a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) m_pendingReaders.append(reader); 172a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) executeReaders(); 173a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) } 174a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) 175d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) FinishReaderType removeReader(FileReader* reader) 176a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) { 177197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch WillBeHeapHashSet<RawPtrWillBeMember<FileReader> >::const_iterator hashIter = m_runningReaders.find(reader); 178a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) if (hashIter != m_runningReaders.end()) { 179a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) m_runningReaders.remove(hashIter); 180d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return RunPendingReaders; 181a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) } 182197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch WillBeHeapDeque<RawPtrWillBeMember<FileReader> >::const_iterator dequeEnd = m_pendingReaders.end(); 183197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch for (WillBeHeapDeque<RawPtrWillBeMember<FileReader> >::const_iterator it = m_pendingReaders.begin(); it != dequeEnd; ++it) { 184a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) if (*it == reader) { 185a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) m_pendingReaders.remove(it); 186d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) break; 187a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) } 188a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) } 189d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return DoNotRunPendingReaders; 190d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } 191d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 192d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) void finishReader(FileReader* reader, FinishReaderType nextStep) 193d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) { 194d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (nextStep == RunPendingReaders) 195d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) executeReaders(); 196a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) } 197a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) 198a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) void executeReaders() 199a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) { 200a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) while (m_runningReaders.size() < m_maxRunningReaders) { 201a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) if (m_pendingReaders.isEmpty()) 202a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) return; 203a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) FileReader* reader = m_pendingReaders.takeFirst(); 204a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) reader->executePendingRead(); 205a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) m_runningReaders.add(reader); 206a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) } 207a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) } 208a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) 209197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch static const char* supplementName() { return "FileReaderThrottlingController"; } 210197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 211a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) const size_t m_maxRunningReaders; 212197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch WillBeHeapDeque<RawPtrWillBeMember<FileReader> > m_pendingReaders; 213197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch WillBeHeapHashSet<RawPtrWillBeMember<FileReader> > m_runningReaders; 214a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)}; 215a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) 216d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)PassRefPtrWillBeRawPtr<FileReader> FileReader::create(ExecutionContext* context) 2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 218197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch RefPtrWillBeRawPtr<FileReader> fileReader(adoptRefWillBeNoop(new FileReader(context))); 2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) fileReader->suspendIfNeeded(); 2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return fileReader.release(); 2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2231e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)FileReader::FileReader(ExecutionContext* context) 224926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) : ActiveDOMObject(context) 2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_state(EMPTY) 2268abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) , m_loadingState(LoadingStateNone) 2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_readType(FileReaderLoader::ReadAsBinaryString) 2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_lastProgressNotificationTimeMS(0) 229c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) , m_asyncOperationId(0) 2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)FileReader::~FileReader() 2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) terminate(); 2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const AtomicString& FileReader::interfaceName() const 2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2401e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) return EventTargetNames::FileReader; 2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void FileReader::stop() 2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2459e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) // The delayed abort task tidies up and advances to the DONE state. 2469e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) if (m_loadingState == LoadingStateAborted) 2479e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) return; 2489e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) 249197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (hasPendingActivity()) 250197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch ThrottlingController::finishReader(executionContext(), this, ThrottlingController::removeReader(executionContext(), this)); 2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) terminate(); 2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 254197021e6b966cfb06891637935ef33fff06433d1Ben Murdochbool FileReader::hasPendingActivity() const 255197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{ 256197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return m_state == LOADING; 257197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch} 258197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 25951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void FileReader::readAsArrayBuffer(Blob* blob, ExceptionState& exceptionState) 2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2619e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) ASSERT(blob); 262a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) WTF_LOG(FileAPI, "FileReader: reading as array buffer: %s %s\n", utf8BlobUUID(blob).data(), utf8FilePath(blob).data()); 2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 26451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) readInternal(blob, FileReaderLoader::ReadAsArrayBuffer, exceptionState); 2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 26751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void FileReader::readAsBinaryString(Blob* blob, ExceptionState& exceptionState) 2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2699e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) ASSERT(blob); 270a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) WTF_LOG(FileAPI, "FileReader: reading as binary: %s %s\n", utf8BlobUUID(blob).data(), utf8FilePath(blob).data()); 2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 27251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) readInternal(blob, FileReaderLoader::ReadAsBinaryString, exceptionState); 2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 27551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void FileReader::readAsText(Blob* blob, const String& encoding, ExceptionState& exceptionState) 2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2779e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) ASSERT(blob); 278a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) WTF_LOG(FileAPI, "FileReader: reading as text: %s %s\n", utf8BlobUUID(blob).data(), utf8FilePath(blob).data()); 2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_encoding = encoding; 28151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) readInternal(blob, FileReaderLoader::ReadAsText, exceptionState); 2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 28451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void FileReader::readAsText(Blob* blob, ExceptionState& exceptionState) 2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 28651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) readAsText(blob, String(), exceptionState); 2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 28951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void FileReader::readAsDataURL(Blob* blob, ExceptionState& exceptionState) 2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2919e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) ASSERT(blob); 292a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) WTF_LOG(FileAPI, "FileReader: reading as data URL: %s %s\n", utf8BlobUUID(blob).data(), utf8FilePath(blob).data()); 2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 29451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) readInternal(blob, FileReaderLoader::ReadAsDataURL, exceptionState); 2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 29751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void FileReader::readInternal(Blob* blob, FileReaderLoader::ReadType type, ExceptionState& exceptionState) 2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 299e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch // If multiple concurrent read methods are called on the same FileReader, InvalidStateError should be thrown when the state is LOADING. 3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_state == LOADING) { 30109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) exceptionState.throwDOMException(InvalidStateError, "The object is already busy reading Blobs."); 3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 305d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (blob->hasBeenClosed()) { 306d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) exceptionState.throwDOMException(InvalidStateError, String(blob->isFile() ? "File" : "Blob") + " has been closed."); 307d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return; 308d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } 309d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 310197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (!ThrottlingController::from(executionContext())) { 311197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch exceptionState.throwDOMException(AbortError, "Reading from a Document-detached FileReader is not supported."); 312197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return; 313197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch } 314197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 315d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // "Snapshot" the Blob data rather than the Blob itself as ongoing 316d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // read operations should not be affected if close() is called on 317d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // the Blob being read. 318d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) m_blobDataHandle = blob->blobDataHandle(); 319d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) m_blobType = blob->type(); 3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_readType = type; 3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_state = LOADING; 322a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) m_loadingState = LoadingStatePending; 323d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) m_error = nullptr; 324197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch ThrottlingController::pushReader(executionContext(), this); 325a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)} 326a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) 327a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)void FileReader::executePendingRead() 328a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles){ 329a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) ASSERT(m_loadingState == LoadingStatePending); 330a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) m_loadingState = LoadingStateLoading; 3315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_loader = adoptPtr(new FileReaderLoader(m_readType, this)); 3335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_loader->setEncoding(m_encoding); 334d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) m_loader->setDataType(m_blobType); 335d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) m_loader->start(executionContext(), m_blobDataHandle); 336d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) m_blobDataHandle = nullptr; 3375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3391e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)static void delayedAbort(ExecutionContext*, FileReader* reader) 3405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) reader->doAbort(); 3425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void FileReader::abort() 3455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 346a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) WTF_LOG(FileAPI, "FileReader: aborting\n"); 3475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 348a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) if (m_loadingState != LoadingStateLoading 349a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) && m_loadingState != LoadingStatePending) { 3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 351a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) } 3528abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) m_loadingState = LoadingStateAborted; 3535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Schedule to have the abort done later since abort() might be called from the event handler and we do not want the resource loading code to be in the stack. 3551e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) executionContext()->postTask( 356197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch createCrossThreadTask(&delayedAbort, AllowAccessLater(this))); 3575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void FileReader::doAbort() 3605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_state != DONE); 3625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) terminate(); 3645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_error = FileError::create(FileError::ABORT_ERR); 3665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 367d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // Unregister the reader. 368197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch ThrottlingController::FinishReaderType finalStep = ThrottlingController::removeReader(executionContext(), this); 369d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 3701e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) fireEvent(EventTypeNames::error); 3711e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) fireEvent(EventTypeNames::abort); 3721e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) fireEvent(EventTypeNames::loadend); 3735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // All possible events have fired and we're done, no more pending activity. 375197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch ThrottlingController::finishReader(executionContext(), this, finalStep); 3765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void FileReader::terminate() 3795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_loader) { 3815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_loader->cancel(); 3825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_loader = nullptr; 3835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_state = DONE; 3858abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) m_loadingState = LoadingStateNone; 3865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void FileReader::didStartLoading() 3895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3901e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) fireEvent(EventTypeNames::loadstart); 3915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void FileReader::didReceiveData() 3945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Fire the progress event at least every 50ms. 3965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double now = currentTimeMS(); 3975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_lastProgressNotificationTimeMS) 3985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_lastProgressNotificationTimeMS = now; 3995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (now - m_lastProgressNotificationTimeMS > progressNotificationIntervalMS) { 4001e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) fireEvent(EventTypeNames::progress); 4015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_lastProgressNotificationTimeMS = now; 4025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void FileReader::didFinishLoading() 4065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4078abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) if (m_loadingState == LoadingStateAborted) 4085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 4098abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) ASSERT(m_loadingState == LoadingStateLoading); 4108abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) 4118abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) // It's important that we change m_loadingState before firing any events 4128abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) // since any of the events could call abort(), which internally checks 4138abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) // if we're still loading (therefore we need abort process) or not. 4148abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) m_loadingState = LoadingStateNone; 4155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4161e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) fireEvent(EventTypeNames::progress); 417e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) 4185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_state != DONE); 4195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_state = DONE; 4205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 421d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // Unregister the reader. 422197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch ThrottlingController::FinishReaderType finalStep = ThrottlingController::removeReader(executionContext(), this); 423d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 4241e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) fireEvent(EventTypeNames::load); 4251e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) fireEvent(EventTypeNames::loadend); 42602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 4275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // All possible events have fired and we're done, no more pending activity. 428197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch ThrottlingController::finishReader(executionContext(), this, finalStep); 4295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 431591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochvoid FileReader::didFail(FileError::ErrorCode errorCode) 4325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4338abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) if (m_loadingState == LoadingStateAborted) 4345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 4358abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) ASSERT(m_loadingState == LoadingStateLoading); 4368abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) m_loadingState = LoadingStateNone; 4375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_state != DONE); 4395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_state = DONE; 4405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_error = FileError::create(static_cast<FileError::ErrorCode>(errorCode)); 442d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 443d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // Unregister the reader. 444197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch ThrottlingController::FinishReaderType finalStep = ThrottlingController::removeReader(executionContext(), this); 445d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 4461e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) fireEvent(EventTypeNames::error); 4471e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) fireEvent(EventTypeNames::loadend); 44802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 4495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // All possible events have fired and we're done, no more pending activity. 450197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch ThrottlingController::finishReader(executionContext(), this, finalStep); 4515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void FileReader::fireEvent(const AtomicString& type) 4545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 455c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) InspectorInstrumentationCookie cookie = InspectorInstrumentation::traceAsyncCallbackStarting(executionContext(), m_asyncOperationId); 456bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) if (!m_loader) { 457bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) dispatchEvent(ProgressEvent::create(type, false, 0, 0)); 458c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) InspectorInstrumentation::traceAsyncCallbackCompleted(cookie); 459bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) return; 460bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) } 461bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 462bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) if (m_loader->totalBytes() >= 0) 463bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) dispatchEvent(ProgressEvent::create(type, true, m_loader->bytesLoaded(), m_loader->totalBytes())); 464bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) else 465bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) dispatchEvent(ProgressEvent::create(type, false, m_loader->bytesLoaded(), 0)); 466c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 467c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) InspectorInstrumentation::traceAsyncCallbackCompleted(cookie); 4685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<ArrayBuffer> FileReader::arrayBufferResult() const 4715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_loader || m_error) 473d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return nullptr; 4745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_loader->arrayBufferResult(); 4755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String FileReader::stringResult() 4785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_loader || m_error) 4805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return String(); 4815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_loader->stringResult(); 4825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 484d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void FileReader::trace(Visitor* visitor) 485d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){ 486d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) visitor->trace(m_error); 487d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) EventTargetWithInlineData::trace(visitor); 488d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)} 489d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 490c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink 491