From 71365c8b72e5a58e2bc994e91c53caa265446784 Mon Sep 17 00:00:00 2001 From: Phil Ringnalda Date: Thu, 4 May 2017 19:26:26 -0700 Subject: [PATCH] Backed out 6 changesets (bug 1360807) for ongoing hangs in test_fileReader.html and test_ipcBlob_fileReaderSync.html CLOSED TREE Backed out changeset 3a05e05fb644 (bug 1360807) Backed out changeset 9630a51eca07 (bug 1360807) Backed out changeset 41e9af8078dd (bug 1360807) Backed out changeset e59616a3997a (bug 1360807) Backed out changeset c800cb830b36 (bug 1360807) Backed out changeset 4ab091bdeda1 (bug 1360807) MozReview-Commit-ID: 1h3pcsPi2An --- .../tests/test_ipcBlob_fileReaderSync.html | 69 ++------- dom/workers/FileReaderSync.cpp | 136 +++--------------- dom/workers/FileReaderSync.h | 7 +- 3 files changed, 32 insertions(+), 180 deletions(-) diff --git a/dom/file/ipc/tests/test_ipcBlob_fileReaderSync.html b/dom/file/ipc/tests/test_ipcBlob_fileReaderSync.html index 2a628987d6aa..814e49c71b41 100644 --- a/dom/file/ipc/tests/test_ipcBlob_fileReaderSync.html +++ b/dom/file/ipc/tests/test_ipcBlob_fileReaderSync.html @@ -13,74 +13,21 @@ function workerScript() { onmessage = function(event) { let readerMemoryBlob = new FileReaderSync(); let status = readerMemoryBlob.readAsText(new Blob(['hello world'])) == 'hello world'; - postMessage({ status, message: "FileReaderSync with memory blob still works" }); - let readerIPCBlob1 = new FileReaderSync(); - postMessage({ blob: event.data, method: 'readAsText', - data: readerIPCBlob1.readAsText(event.data)}); - - let readerIPCBlob2 = new FileReaderSync(); - postMessage({ blob: event.data, method: 'readAsArrayBuffer', - data: readerIPCBlob2.readAsArrayBuffer(event.data)}); - - let readerIPCBlob3 = new FileReaderSync(); - postMessage({ blob: event.data, method: 'readAsDataURL', - data: readerIPCBlob3.readAsDataURL(event.data)}); - - let multipartBlob = new Blob(['wow', event.data]); - - let readerIPCBlobMultipart1 = new FileReaderSync(); - postMessage({ blob: multipartBlob, method: 'readAsText', - data: readerIPCBlobMultipart1.readAsText(multipartBlob)}); - - let readerIPCBlobMultipart2 = new FileReaderSync(); - postMessage({ blob: multipartBlob, method: 'readAsArrayBuffer', - data: readerIPCBlobMultipart2.readAsArrayBuffer(multipartBlob)}); - - let readerIPCBlobMultipart3 = new FileReaderSync(); - postMessage({ blob: multipartBlob, method: 'readAsDataURL', - data: readerIPCBlobMultipart3.readAsDataURL(multipartBlob)}); - - postMessage({ finish: true }); - } -} - -let completed = false; -let pendingTasks = 0; -function maybeFinish() { - if (completed && !pendingTasks) { - SimpleTest.finish(); + let readerIPCBlob = new FileReaderSync(); + postMessage({ blob: event.data, data: readerIPCBlob.readAsText(event.data), status }); } } let workerUrl = URL.createObjectURL(new Blob(["(", workerScript.toSource(), ")()"])); let worker = new Worker(workerUrl); worker.onmessage = event => { - if ("status" in event.data) { - ok(event.data.status, event.data.message); - return; - } - - if ("blob" in event.data) { - let fr = new FileReader(); - fr[event.data.method](event.data.blob); - ++pendingTasks; - fr.onload = () => { - if (event.data.method != 'readAsArrayBuffer') { - is(event.data.data, fr.result, "The file has been read"); - } else { - is(event.data.data.byteLength, fr.result.byteLength, "The file has been read"); - } - --pendingTasks; - maybeFinish(); - } - - return; - } - - if ("finish" in event.data) { - completed = true; - maybeFinish(); + let fr = new FileReader(); + fr.readAsText(event.data.blob); + fr.onload = () => { + is(event.data.data, fr.result, "The file has been read"); + ok(event.data.status, "FileReaderSync with memory blob still works"); + SimpleTest.finish(); } }; diff --git a/dom/workers/FileReaderSync.cpp b/dom/workers/FileReaderSync.cpp index a8da4abd3ea9..4bf8e5fd6d06 100644 --- a/dom/workers/FileReaderSync.cpp +++ b/dom/workers/FileReaderSync.cpp @@ -21,7 +21,6 @@ #include "nsIConverterInputStream.h" #include "nsIInputStream.h" #include "nsIMultiplexInputStream.h" -#include "nsStreamUtils.h" #include "nsStringStream.h" #include "nsISupportsImpl.h" #include "nsNetUtil.h" @@ -79,16 +78,11 @@ FileReaderSync::ReadAsArrayBuffer(JSContext* aCx, } uint32_t numRead; - aRv = SyncRead(stream, bufferData.get(), blobSize, &numRead); + aRv = Read(stream, bufferData.get(), blobSize, &numRead); if (NS_WARN_IF(aRv.Failed())) { return; } - - // The file is changed in the meantime? - if (numRead != blobSize) { - aRv.Throw(NS_ERROR_FAILURE); - return; - } + NS_ASSERTION(numRead == blobSize, "failed to read data"); JSObject* arrayBuffer = JS_NewArrayBufferWithContents(aCx, blobSize, bufferData.get()); if (!arrayBuffer) { @@ -116,7 +110,7 @@ FileReaderSync::ReadAsBinaryString(Blob& aBlob, uint32_t numRead; do { char readBuf[4096]; - aRv = SyncRead(stream, readBuf, sizeof(readBuf), &numRead); + aRv = Read(stream, readBuf, sizeof(readBuf), &numRead); if (NS_WARN_IF(aRv.Failed())) { return; } @@ -151,17 +145,11 @@ FileReaderSync::ReadAsText(Blob& aBlob, } uint32_t numRead = 0; - aRv = SyncRead(stream, sniffBuf.BeginWriting(), sniffBuf.Length(), &numRead); + aRv = Read(stream, sniffBuf.BeginWriting(), sniffBuf.Length(), &numRead); if (NS_WARN_IF(aRv.Failed())) { return; } - // No data, we don't need to continue. - if (numRead == 0) { - aResult.Truncate(); - return; - } - // The BOM sniffing is baked into the "decode" part of the Encoding // Standard, which the File API references. if (!nsContentUtils::CheckForBOM((const unsigned char*)sniffBuf.BeginReading(), @@ -194,10 +182,16 @@ FileReaderSync::ReadAsText(Blob& aBlob, } // Let's recreate the full stream using a: - // multiplexStream(syncStream + original stream) + // multiplexStream(stringStream + original stream) // In theory, we could try to see if the inputStream is a nsISeekableStream, // but this doesn't work correctly for nsPipe3 - See bug 1349570. + nsCOMPtr stringStream; + aRv = NS_NewCStringInputStream(getter_AddRefs(stringStream), sniffBuf); + if (NS_WARN_IF(aRv.Failed())) { + return; + } + nsCOMPtr multiplexStream = do_CreateInstance("@mozilla.org/io/multiplex-input-stream;1"); if (NS_WARN_IF(!multiplexStream)) { @@ -205,24 +199,12 @@ FileReaderSync::ReadAsText(Blob& aBlob, return; } - nsCOMPtr sniffStringStream; - aRv = NS_NewCStringInputStream(getter_AddRefs(sniffStringStream), sniffBuf); + aRv = multiplexStream->AppendStream(stringStream); if (NS_WARN_IF(aRv.Failed())) { return; } - aRv = multiplexStream->AppendStream(sniffStringStream); - if (NS_WARN_IF(aRv.Failed())) { - return; - } - - nsCOMPtr syncStream; - aRv = ConvertAsyncToSyncStream(stream, getter_AddRefs(syncStream)); - if (NS_WARN_IF(aRv.Failed())) { - return; - } - - aRv = multiplexStream->AppendStream(syncStream); + aRv = multiplexStream->AppendStream(stream); if (NS_WARN_IF(aRv.Failed())) { return; } @@ -256,30 +238,19 @@ FileReaderSync::ReadAsDataURL(Blob& aBlob, nsAString& aResult, return; } - nsCOMPtr syncStream; - aRv = ConvertAsyncToSyncStream(stream, getter_AddRefs(syncStream)); - if (NS_WARN_IF(aRv.Failed())) { - return; - } - - uint64_t size; - aRv = syncStream->Available(&size); - if (NS_WARN_IF(aRv.Failed())) { - return; - } - - uint64_t blobSize = aBlob.GetSize(aRv); + uint64_t size = aBlob.GetSize(aRv); if (NS_WARN_IF(aRv.Failed())){ return; } - // The file is changed in the meantime? - if (blobSize != size) { + nsCOMPtr bufferedStream; + aRv = NS_NewBufferedInputStream(getter_AddRefs(bufferedStream), stream, size); + if (NS_WARN_IF(aRv.Failed())){ return; } nsAutoString encodedData; - aRv = Base64EncodeInputStream(syncStream, encodedData, size); + aRv = Base64EncodeInputStream(bufferedStream, encodedData, size); if (NS_WARN_IF(aRv.Failed())){ return; } @@ -390,8 +361,8 @@ NS_INTERFACE_MAP_END } // anonymous nsresult -FileReaderSync::SyncRead(nsIInputStream* aStream, char* aBuffer, - uint32_t aBufferSize, uint32_t* aRead) +FileReaderSync::Read(nsIInputStream* aStream, char* aBuffer, uint32_t aBufferSize, + uint32_t* aRead) { MOZ_ASSERT(aStream); MOZ_ASSERT(aBuffer); @@ -399,34 +370,10 @@ FileReaderSync::SyncRead(nsIInputStream* aStream, char* aBuffer, // Let's try to read, directly. nsresult rv = aStream->Read(aBuffer, aBufferSize, aRead); - - // Nothing else to read. - if (rv == NS_BASE_STREAM_CLOSED || - (NS_SUCCEEDED(rv) && *aRead == 0)) { - return NS_OK; - } - - // An error. - if (NS_FAILED(rv) && rv != NS_BASE_STREAM_WOULD_BLOCK) { + if (NS_SUCCEEDED(rv) || rv != NS_BASE_STREAM_WOULD_BLOCK) { return rv; } - // All good. - if (NS_SUCCEEDED(rv)) { - // Not enough data, let's read recursively. - if (*aRead != aBufferSize) { - uint32_t byteRead = 0; - rv = SyncRead(aStream, aBuffer + *aRead, aBufferSize - *aRead, &byteRead); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - *aRead += byteRead; - } - - return NS_OK; - } - // We need to proceed async. nsCOMPtr asyncStream = do_QueryInterface(aStream); if (!asyncStream) { @@ -461,44 +408,5 @@ FileReaderSync::SyncRead(nsIInputStream* aStream, char* aBuffer, } // Now, we can try to read again. - return SyncRead(aStream, aBuffer, aBufferSize, aRead); -} - -nsresult -FileReaderSync::ConvertAsyncToSyncStream(nsIInputStream* aAsyncStream, - nsIInputStream** aSyncStream) -{ - // If the stream is not async, we just need it to be bufferable. - nsCOMPtr asyncStream = do_QueryInterface(aAsyncStream); - if (!asyncStream) { - return NS_NewBufferedInputStream(aSyncStream, aAsyncStream, 4096); - } - - uint64_t length; - nsresult rv = aAsyncStream->Available(&length); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - nsAutoCString buffer; - if (!buffer.SetLength(length, fallible)) { - return NS_ERROR_OUT_OF_MEMORY; - } - - uint32_t read; - rv = SyncRead(aAsyncStream, buffer.BeginWriting(), length, &read); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - if (read != length) { - return NS_ERROR_FAILURE; - } - - rv = NS_NewCStringInputStream(aSyncStream, buffer); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - return NS_OK; + return Read(aStream, aBuffer, aBufferSize, aRead); } diff --git a/dom/workers/FileReaderSync.h b/dom/workers/FileReaderSync.h index 6b61f039ee8a..c23803161b92 100644 --- a/dom/workers/FileReaderSync.h +++ b/dom/workers/FileReaderSync.h @@ -32,11 +32,8 @@ private: nsresult ConvertStream(nsIInputStream *aStream, const char *aCharset, nsAString &aResult); - nsresult ConvertAsyncToSyncStream(nsIInputStream* aAsyncStream, - nsIInputStream** aSyncStream); - - nsresult SyncRead(nsIInputStream* aStream, char* aBuffer, - uint32_t aBufferSize, uint32_t* aRead); + nsresult Read(nsIInputStream* aStream, char* aBuffer, uint32_t aBufferSize, + uint32_t* aRead); public: static already_AddRefed