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

Unified Diff: Source/core/fileapi/FileReader.cpp

Issue 399863002: Gracefully handle FileReader() read operations when in a detached state. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Throw AbortError (instead of InvalidStateError.) Created 6 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 | « Source/core/fileapi/FileReader.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/fileapi/FileReader.cpp
diff --git a/Source/core/fileapi/FileReader.cpp b/Source/core/fileapi/FileReader.cpp
index 9a3f948c257b6e5611ea38534e2ebf2a3a674e65..88789491569d909d62e03d3610da9572637ade27 100644
--- a/Source/core/fileapi/FileReader.cpp
+++ b/Source/core/fileapi/FileReader.cpp
@@ -75,11 +75,16 @@ const CString utf8FilePath(Blob* blob)
static const size_t kMaxOutstandingRequestsPerThread = 100;
static const double progressNotificationIntervalMS = 50;
+// FIXME: Oilpan: if ExecutionContext is moved to the heap, consider
+// making this object an ExecutionContext supplement (only.)
class FileReader::ThrottlingController FINAL : public NoBaseWillBeGarbageCollectedFinalized<FileReader::ThrottlingController>, public WillBeHeapSupplement<LocalFrame>, public WillBeHeapSupplement<WorkerClients> {
WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(FileReader::ThrottlingController);
public:
static ThrottlingController* from(ExecutionContext* context)
{
+ if (!context)
+ return 0;
+
if (context->isDocument()) {
Document* document = toDocument(context);
if (!document->frame())
@@ -109,6 +114,49 @@ public:
enum FinishReaderType { DoNotRunPendingReaders, RunPendingReaders };
+ static void pushReader(ExecutionContext* context, FileReader* reader)
+ {
+ ThrottlingController* controller = from(context);
+ if (!controller)
+ return;
+
+ controller->pushReader(reader);
+ }
+
+ static FinishReaderType removeReader(ExecutionContext* context, FileReader* reader)
+ {
+ ThrottlingController* controller = from(context);
+ if (!controller)
+ return DoNotRunPendingReaders;
+
+ return controller->removeReader(reader);
+ }
+
+ static void finishReader(ExecutionContext* context, FileReader* reader, FinishReaderType nextStep)
+ {
+ ThrottlingController* controller = from(context);
+ if (!controller)
+ return;
+
+ controller->finishReader(reader, nextStep);
+ }
+
+ void trace(Visitor* visitor)
+ {
+#if ENABLE(OILPAN)
+ visitor->trace(m_pendingReaders);
+ visitor->trace(m_runningReaders);
+#endif
+ WillBeHeapSupplement<LocalFrame>::trace(visitor);
+ WillBeHeapSupplement<WorkerClients>::trace(visitor);
+ }
+
+private:
+ ThrottlingController()
+ : m_maxRunningReaders(kMaxOutstandingRequestsPerThread)
+ {
+ }
+
void pushReader(FileReader* reader)
{
if (m_pendingReaders.isEmpty()
@@ -145,22 +193,6 @@ public:
executeReaders();
}
- void trace(Visitor* visitor)
- {
-#if ENABLE(OILPAN)
- visitor->trace(m_pendingReaders);
- visitor->trace(m_runningReaders);
-#endif
- WillBeHeapSupplement<LocalFrame>::trace(visitor);
- WillBeHeapSupplement<WorkerClients>::trace(visitor);
- }
-
-private:
- ThrottlingController()
- : m_maxRunningReaders(kMaxOutstandingRequestsPerThread)
- {
- }
-
void executeReaders()
{
while (m_runningReaders.size() < m_maxRunningReaders) {
@@ -209,7 +241,7 @@ const AtomicString& FileReader::interfaceName() const
void FileReader::stop()
{
if (hasPendingActivity())
- throttlingController()->finishReader(this, throttlingController()->removeReader(this));
+ ThrottlingController::finishReader(executionContext(), this, ThrottlingController::removeReader(executionContext(), this));
terminate();
}
@@ -285,6 +317,11 @@ void FileReader::readInternal(Blob* blob, FileReaderLoader::ReadType type, Excep
return;
}
+ if (!ThrottlingController::from(executionContext())) {
+ exceptionState.throwDOMException(AbortError, "Reading from a Document-detached FileReader is not supported.");
+ return;
+ }
+
// "Snapshot" the Blob data rather than the Blob itself as ongoing
// read operations should not be affected if close() is called on
// the Blob being read.
@@ -294,7 +331,7 @@ void FileReader::readInternal(Blob* blob, FileReaderLoader::ReadType type, Excep
m_state = LOADING;
m_loadingState = LoadingStatePending;
m_error = nullptr;
- throttlingController()->pushReader(this);
+ ThrottlingController::pushReader(executionContext(), this);
}
void FileReader::executePendingRead()
@@ -338,14 +375,14 @@ void FileReader::doAbort()
m_error = FileError::create(FileError::ABORT_ERR);
// Unregister the reader.
- ThrottlingController::FinishReaderType finalStep = throttlingController()->removeReader(this);
+ ThrottlingController::FinishReaderType finalStep = ThrottlingController::removeReader(executionContext(), this);
fireEvent(EventTypeNames::error);
fireEvent(EventTypeNames::abort);
fireEvent(EventTypeNames::loadend);
// All possible events have fired and we're done, no more pending activity.
- throttlingController()->finishReader(this, finalStep);
+ ThrottlingController::finishReader(executionContext(), this, finalStep);
}
void FileReader::terminate()
@@ -392,13 +429,13 @@ void FileReader::didFinishLoading()
m_state = DONE;
// Unregister the reader.
- ThrottlingController::FinishReaderType finalStep = throttlingController()->removeReader(this);
+ ThrottlingController::FinishReaderType finalStep = ThrottlingController::removeReader(executionContext(), this);
fireEvent(EventTypeNames::load);
fireEvent(EventTypeNames::loadend);
// All possible events have fired and we're done, no more pending activity.
- throttlingController()->finishReader(this, finalStep);
+ ThrottlingController::finishReader(executionContext(), this, finalStep);
}
void FileReader::didFail(FileError::ErrorCode errorCode)
@@ -414,13 +451,13 @@ void FileReader::didFail(FileError::ErrorCode errorCode)
m_error = FileError::create(static_cast<FileError::ErrorCode>(errorCode));
// Unregister the reader.
- ThrottlingController::FinishReaderType finalStep = throttlingController()->removeReader(this);
+ ThrottlingController::FinishReaderType finalStep = ThrottlingController::removeReader(executionContext(), this);
fireEvent(EventTypeNames::error);
fireEvent(EventTypeNames::loadend);
// All possible events have fired and we're done, no more pending activity.
- throttlingController()->finishReader(this, finalStep);
+ ThrottlingController::finishReader(executionContext(), this, finalStep);
}
void FileReader::fireEvent(const AtomicString& type)
@@ -436,11 +473,6 @@ void FileReader::fireEvent(const AtomicString& type)
dispatchEvent(ProgressEvent::create(type, false, m_loader->bytesLoaded(), 0));
}
-FileReader::ThrottlingController* FileReader::throttlingController()
-{
- return FileReader::ThrottlingController::from(executionContext());
-}
-
PassRefPtr<ArrayBuffer> FileReader::arrayBufferResult() const
{
if (!m_loader || m_error)
« no previous file with comments | « Source/core/fileapi/FileReader.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698