зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 4 changesets (bug 1360807) for a 30% failure rate in test_ipcBlob_fileReaderSync.html on ASan e10s a=merge
Backed out changeset b7790c232791 (bug 1360807) Backed out changeset 50d6d6733209 (bug 1360807) Backed out changeset 6e84dfab90bf (bug 1360807) Backed out changeset f25d7a76008e (bug 1360807) MozReview-Commit-ID: DTkQJz5ZYMD --HG-- extra : source : 6b0f7ac46e1f81cd72931aaee41f4863d8d8876d
This commit is contained in:
Родитель
efab9f9365
Коммит
0a18b0efae
|
@ -645,10 +645,10 @@ FileReader::OnInputStreamReady(nsIAsyncInputStream* aStream)
|
|||
|
||||
if (NS_SUCCEEDED(rv) && count) {
|
||||
rv = DoReadData(count);
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = DoAsyncWait();
|
||||
}
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = DoAsyncWait();
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv) || !count) {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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<nsIInputStream> stringStream;
|
||||
aRv = NS_NewCStringInputStream(getter_AddRefs(stringStream), sniffBuf);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIMultiplexInputStream> 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<nsIInputStream> 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<nsIInputStream> 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<nsIInputStream> 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<nsIInputStream> 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<nsIAsyncInputStream> 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<nsIAsyncInputStream> 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);
|
||||
}
|
||||
|
|
|
@ -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<FileReaderSync>
|
||||
|
|
Загрузка…
Ссылка в новой задаче