mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-18 14:56:07 +00:00
Bug 1502403 - FileReader should dispatch loadstart asynchronously, r=smaug,ssengupta
Differential Revision: https://phabricator.services.mozilla.com/D78852
This commit is contained in:
parent
2ff52580c4
commit
b058e12e25
@ -84,6 +84,28 @@ class MOZ_RAII FileReaderDecreaseBusyCounter {
|
||||
~FileReaderDecreaseBusyCounter() { mFileReader->DecreaseBusyCounter(); }
|
||||
};
|
||||
|
||||
class FileReader::AsyncWaitRunnable final : public CancelableRunnable {
|
||||
public:
|
||||
explicit AsyncWaitRunnable(FileReader* aReader)
|
||||
: CancelableRunnable("FileReader::AsyncWaitRunnable"), mReader(aReader) {}
|
||||
|
||||
NS_IMETHOD
|
||||
Run() override {
|
||||
if (mReader) {
|
||||
mReader->InitialAsyncWait();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult Cancel() override {
|
||||
mReader = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
public:
|
||||
RefPtr<FileReader> mReader;
|
||||
};
|
||||
|
||||
void FileReader::RootResultArrayBuffer() { mozilla::HoldJSObjects(this); }
|
||||
|
||||
// FileReader constructors/initializers
|
||||
@ -156,7 +178,7 @@ void FileReader::GetResult(JSContext* aCx,
|
||||
return;
|
||||
}
|
||||
|
||||
if (mResult.IsVoid()) {
|
||||
if (mReadyState != DONE || mResult.IsVoid()) {
|
||||
aResult.SetNull();
|
||||
return;
|
||||
}
|
||||
@ -400,7 +422,8 @@ void FileReader::ReadFileContent(Blob& aBlob, const nsAString& aCharset,
|
||||
}
|
||||
}
|
||||
|
||||
aRv = DoAsyncWait();
|
||||
mAsyncWaitRunnable = new AsyncWaitRunnable(this);
|
||||
aRv = NS_DispatchToCurrentThread(mAsyncWaitRunnable);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
FreeFileData();
|
||||
return;
|
||||
@ -408,6 +431,18 @@ void FileReader::ReadFileContent(Blob& aBlob, const nsAString& aCharset,
|
||||
|
||||
// FileReader should be in loading state here
|
||||
mReadyState = LOADING;
|
||||
}
|
||||
|
||||
void FileReader::InitialAsyncWait() {
|
||||
mAsyncWaitRunnable = nullptr;
|
||||
|
||||
nsresult rv = DoAsyncWait();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
mReadyState = EMPTY;
|
||||
FreeFileData();
|
||||
return;
|
||||
}
|
||||
|
||||
DispatchProgressEvent(NS_LITERAL_STRING(LOADSTART_STR));
|
||||
}
|
||||
|
||||
@ -694,6 +729,11 @@ void FileReader::Abort() {
|
||||
|
||||
ClearProgressEventTimer();
|
||||
|
||||
if (mAsyncWaitRunnable) {
|
||||
mAsyncWaitRunnable->Cancel();
|
||||
mAsyncWaitRunnable = nullptr;
|
||||
}
|
||||
|
||||
mReadyState = DONE;
|
||||
|
||||
// XXX The spec doesn't say this
|
||||
@ -703,6 +743,20 @@ void FileReader::Abort() {
|
||||
SetDOMStringToNull(mResult);
|
||||
mResultArrayBuffer = nullptr;
|
||||
|
||||
// If we have the stream and the busy-count is not 0, it means that we are
|
||||
// waiting for an OnInputStreamReady() call. Let's abort the current
|
||||
// AsyncWait() calling it again with a nullptr callback. See
|
||||
// nsIAsyncInputStream.idl.
|
||||
if (mAsyncStream && mBusyCount) {
|
||||
mAsyncStream->AsyncWait(/* callback */ nullptr,
|
||||
/* aFlags*/ 0,
|
||||
/* aRequestedCount */ 0, mTarget);
|
||||
DecreaseBusyCounter();
|
||||
MOZ_ASSERT(mBusyCount == 0);
|
||||
|
||||
mAsyncStream->Close();
|
||||
}
|
||||
|
||||
mAsyncStream = nullptr;
|
||||
mBlob = nullptr;
|
||||
|
||||
@ -712,7 +766,7 @@ void FileReader::Abort() {
|
||||
// Dispatch the events
|
||||
DispatchProgressEvent(NS_LITERAL_STRING(ABORT_STR));
|
||||
DispatchProgressEvent(NS_LITERAL_STRING(LOADEND_STR));
|
||||
}
|
||||
} // namespace dom
|
||||
|
||||
nsresult FileReader::IncreaseBusyCounter() {
|
||||
if (mWeakWorkerRef && mBusyCount++ == 0) {
|
||||
@ -745,6 +799,11 @@ void FileReader::DecreaseBusyCounter() {
|
||||
void FileReader::Shutdown() {
|
||||
mReadyState = DONE;
|
||||
|
||||
if (mAsyncWaitRunnable) {
|
||||
mAsyncWaitRunnable->Cancel();
|
||||
mAsyncWaitRunnable = nullptr;
|
||||
}
|
||||
|
||||
if (mAsyncStream) {
|
||||
mAsyncStream->Close();
|
||||
mAsyncStream = nullptr;
|
||||
|
@ -117,6 +117,8 @@ class FileReader final : public DOMEventTargetHelper,
|
||||
eDataFormat DataFormat() const { return mDataFormat; }
|
||||
const nsString& Result() const { return mResult; }
|
||||
|
||||
void InitialAsyncWait();
|
||||
|
||||
private:
|
||||
virtual ~FileReader();
|
||||
|
||||
@ -191,6 +193,10 @@ class FileReader final : public DOMEventTargetHelper,
|
||||
// This value is set when the reading starts in order to keep the worker alive
|
||||
// during the process.
|
||||
RefPtr<StrongWorkerRef> mStrongWorkerRef;
|
||||
|
||||
// Runnable to start the reading asynchronous.
|
||||
class AsyncWaitRunnable;
|
||||
RefPtr<AsyncWaitRunnable> mAsyncWaitRunnable;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(FileReader, FILEREADER_ID)
|
||||
|
@ -344,7 +344,7 @@ function test_readAsText(blob, text) {
|
||||
|
||||
is(r.readyState, FileReader.LOADING, "correct loading text readyState");
|
||||
is(onloadHasRun, false, "text loading must be async");
|
||||
is(onloadStartHasRun, true, "text loadstart should fire sync");
|
||||
is(onloadStartHasRun, false, "text loadstart should fire async");
|
||||
});
|
||||
}
|
||||
|
||||
@ -378,7 +378,7 @@ function test_readAsBinaryString(blob, text) {
|
||||
|
||||
is(r.readyState, FileReader.LOADING, "correct loading binary readyState");
|
||||
is(onloadHasRun, false, "binary loading must be async");
|
||||
is(onloadStartHasRun, true, "binary loadstart should fire sync");
|
||||
is(onloadStartHasRun, false, "binary loadstart should fire async");
|
||||
});
|
||||
}
|
||||
|
||||
@ -419,7 +419,7 @@ function test_readAsArrayBuffer(blob, text) {
|
||||
"correct loading arrayBuffer readyState"
|
||||
);
|
||||
is(onloadHasRun, false, "arrayBuffer loading must be async");
|
||||
is(onloadStartHasRun, true, "arrayBuffer loadstart should fire sync");
|
||||
is(onloadStartHasRun, false, "arrayBuffer loadstart should fire sync");
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1,4 +0,0 @@
|
||||
[filereader_abort.html]
|
||||
[Aborting after read]
|
||||
expected: FAIL
|
||||
|
@ -1,15 +0,0 @@
|
||||
[filereader_events.any.html]
|
||||
[events are dispatched in the correct order for a non-empty blob]
|
||||
expected: FAIL
|
||||
|
||||
[events are dispatched in the correct order for an empty blob]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[filereader_events.any.worker.html]
|
||||
[events are dispatched in the correct order for a non-empty blob]
|
||||
expected: FAIL
|
||||
|
||||
[events are dispatched in the correct order for an empty blob]
|
||||
expected: FAIL
|
||||
|
@ -1,16 +0,0 @@
|
||||
[filereader_result.html]
|
||||
[result is null during "loadstart" event for readAsBinaryString]
|
||||
expected: FAIL
|
||||
|
||||
[result is null during "loadstart" event for readAsDataURL]
|
||||
expected: FAIL
|
||||
|
||||
[result is null during "progress" event for readAsBinaryString]
|
||||
expected: FAIL
|
||||
|
||||
[result is null during "loadstart" event for readAsArrayBuffer]
|
||||
expected: FAIL
|
||||
|
||||
[result is null during "loadstart" event for readAsText]
|
||||
expected: FAIL
|
||||
|
Loading…
x
Reference in New Issue
Block a user