| Index: Source/core/fileapi/FileReader.cpp
|
| diff --git a/Source/core/fileapi/FileReader.cpp b/Source/core/fileapi/FileReader.cpp
|
| index 012d118b6a57988c1a56fbdc0da7cbf0870b2c48..d1f970158e0cc78b09e2580658f302fd976eefd7 100644
|
| --- a/Source/core/fileapi/FileReader.cpp
|
| +++ b/Source/core/fileapi/FileReader.cpp
|
| @@ -75,12 +75,15 @@ public:
|
| ThrottlingController() : m_maxRunningReaders(kMaxOutstandingRequestsPerThread) { }
|
| ~ThrottlingController() { }
|
|
|
| + enum FinishReaderType { DoNotRunPendingReaders, RunPendingReaders };
|
| +
|
| void pushReader(FileReader* reader)
|
| {
|
| reader->setPendingActivity(reader);
|
| if (m_pendingReaders.isEmpty()
|
| && m_runningReaders.size() < m_maxRunningReaders) {
|
| reader->executePendingRead();
|
| + ASSERT(!m_runningReaders.contains(reader));
|
| m_runningReaders.add(reader);
|
| return;
|
| }
|
| @@ -88,23 +91,28 @@ public:
|
| executeReaders();
|
| }
|
|
|
| - void removeReader(FileReader* reader)
|
| + FinishReaderType removeReader(FileReader* reader)
|
| {
|
| HashSet<FileReader*>::const_iterator hashIter = m_runningReaders.find(reader);
|
| if (hashIter != m_runningReaders.end()) {
|
| m_runningReaders.remove(hashIter);
|
| - reader->unsetPendingActivity(reader);
|
| - executeReaders();
|
| - return;
|
| + return RunPendingReaders;
|
| }
|
| Deque<FileReader*>::const_iterator dequeEnd = m_pendingReaders.end();
|
| for (Deque<FileReader*>::const_iterator it = m_pendingReaders.begin(); it != dequeEnd; ++it) {
|
| if (*it == reader) {
|
| m_pendingReaders.remove(it);
|
| - reader->unsetPendingActivity(reader);
|
| - return;
|
| + break;
|
| }
|
| }
|
| + return DoNotRunPendingReaders;
|
| + }
|
| +
|
| + void finishReader(FileReader* reader, FinishReaderType nextStep)
|
| + {
|
| + reader->unsetPendingActivity(reader);
|
| + if (nextStep == RunPendingReaders)
|
| + executeReaders();
|
| }
|
|
|
| private:
|
| @@ -154,7 +162,7 @@ const AtomicString& FileReader::interfaceName() const
|
| void FileReader::stop()
|
| {
|
| if (m_loadingState == LoadingStateLoading || m_loadingState == LoadingStatePending)
|
| - throttlingController()->removeReader(this);
|
| + throttlingController()->finishReader(this, throttlingController()->removeReader(this));
|
| terminate();
|
| }
|
|
|
| @@ -267,12 +275,15 @@ void FileReader::doAbort()
|
|
|
| m_error = FileError::create(FileError::ABORT_ERR);
|
|
|
| + // Unregister the reader.
|
| + ThrottlingController::FinishReaderType finalStep = throttlingController()->removeReader(this);
|
| +
|
| fireEvent(EventTypeNames::error);
|
| fireEvent(EventTypeNames::abort);
|
| fireEvent(EventTypeNames::loadend);
|
|
|
| // All possible events have fired and we're done, no more pending activity.
|
| - throttlingController()->removeReader(this);
|
| + throttlingController()->finishReader(this, finalStep);
|
| }
|
|
|
| void FileReader::terminate()
|
| @@ -318,11 +329,14 @@ void FileReader::didFinishLoading()
|
| ASSERT(m_state != DONE);
|
| m_state = DONE;
|
|
|
| + // Unregister the reader.
|
| + ThrottlingController::FinishReaderType finalStep = throttlingController()->removeReader(this);
|
| +
|
| fireEvent(EventTypeNames::load);
|
| fireEvent(EventTypeNames::loadend);
|
|
|
| // All possible events have fired and we're done, no more pending activity.
|
| - throttlingController()->removeReader(this);
|
| + throttlingController()->finishReader(this, finalStep);
|
| }
|
|
|
| void FileReader::didFail(FileError::ErrorCode errorCode)
|
| @@ -336,11 +350,15 @@ void FileReader::didFail(FileError::ErrorCode errorCode)
|
| m_state = DONE;
|
|
|
| m_error = FileError::create(static_cast<FileError::ErrorCode>(errorCode));
|
| +
|
| + // Unregister the reader.
|
| + ThrottlingController::FinishReaderType finalStep = throttlingController()->removeReader(this);
|
| +
|
| fireEvent(EventTypeNames::error);
|
| fireEvent(EventTypeNames::loadend);
|
|
|
| // All possible events have fired and we're done, no more pending activity.
|
| - throttlingController()->removeReader(this);
|
| + throttlingController()->finishReader(this, finalStep);
|
| }
|
|
|
| void FileReader::fireEvent(const AtomicString& type)
|
|
|