Loading content/canvas/src/ImageEncoder.cpp +48 −17 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ public: , mScriptContext(aScriptContext) , mEncoderThread(aEncoderThread) , mCallback(&aCallback) , mFailed(false) {} virtual ~EncodingCompleteEvent() {} Loading @@ -31,6 +32,9 @@ public: { MOZ_ASSERT(NS_IsMainThread()); mozilla::ErrorResult rv; if (!mFailed) { nsRefPtr<nsDOMMemoryFile> blob = new nsDOMMemoryFile(mImgData, mImgSize, mType); Loading @@ -41,9 +45,15 @@ public: } } mozilla::ErrorResult rv; mCallback->Call(blob, rv); NS_ENSURE_SUCCESS(rv.ErrorCode(), rv.ErrorCode()); } // These members aren't thread-safe. We're making sure that they're being // released on the main thread here. Otherwise, they could be getting // released by EncodingRunnable's destructor on the encoding thread // (bug 916128). mScriptContext = nullptr; mCallback = nullptr; mEncoderThread->Shutdown(); return rv.ErrorCode(); Loading @@ -56,6 +66,11 @@ public: mType = aType; } void SetFailed() { mFailed = true; } private: uint64_t mImgSize; nsAutoString mType; Loading @@ -63,6 +78,7 @@ private: nsCOMPtr<nsIScriptContext> mScriptContext; nsCOMPtr<nsIThread> mEncoderThread; nsRefPtr<FileCallback> mCallback; bool mFailed; }; NS_IMPL_ISUPPORTS1(EncodingCompleteEvent, nsIRunnable); Loading Loading @@ -91,7 +107,7 @@ public: {} virtual ~EncodingRunnable() {} NS_IMETHOD Run() nsresult ProcessImageData(uint64_t* aImgSize, void** aImgData) { nsCOMPtr<nsIInputStream> stream; nsresult rv = ImageEncoder::ExtractDataInternal(mType, Loading @@ -117,18 +133,33 @@ public: } NS_ENSURE_SUCCESS(rv, rv); uint64_t imgSize; rv = stream->Available(&imgSize); rv = stream->Available(aImgSize); NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_TRUE(imgSize <= UINT32_MAX, NS_ERROR_FILE_TOO_BIG); NS_ENSURE_TRUE(*aImgSize <= UINT32_MAX, NS_ERROR_FILE_TOO_BIG); void* imgData = nullptr; rv = NS_ReadInputStreamToBuffer(stream, &imgData, imgSize); rv = NS_ReadInputStreamToBuffer(stream, aImgData, *aImgSize); NS_ENSURE_SUCCESS(rv, rv); return rv; } NS_IMETHOD Run() { uint64_t imgSize; void* imgData = nullptr; nsresult rv = ProcessImageData(&imgSize, &imgData); if (NS_FAILED(rv)) { mEncodingCompleteEvent->SetFailed(); } else { mEncodingCompleteEvent->SetMembers(imgData, imgSize, mType); } rv = NS_DispatchToMainThread(mEncodingCompleteEvent, NS_DISPATCH_NORMAL); NS_ENSURE_SUCCESS(rv, rv); if (NS_FAILED(rv)) { // Better to leak than to crash. mEncodingCompleteEvent.forget(); return rv; } return rv; } Loading Loading
content/canvas/src/ImageEncoder.cpp +48 −17 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ public: , mScriptContext(aScriptContext) , mEncoderThread(aEncoderThread) , mCallback(&aCallback) , mFailed(false) {} virtual ~EncodingCompleteEvent() {} Loading @@ -31,6 +32,9 @@ public: { MOZ_ASSERT(NS_IsMainThread()); mozilla::ErrorResult rv; if (!mFailed) { nsRefPtr<nsDOMMemoryFile> blob = new nsDOMMemoryFile(mImgData, mImgSize, mType); Loading @@ -41,9 +45,15 @@ public: } } mozilla::ErrorResult rv; mCallback->Call(blob, rv); NS_ENSURE_SUCCESS(rv.ErrorCode(), rv.ErrorCode()); } // These members aren't thread-safe. We're making sure that they're being // released on the main thread here. Otherwise, they could be getting // released by EncodingRunnable's destructor on the encoding thread // (bug 916128). mScriptContext = nullptr; mCallback = nullptr; mEncoderThread->Shutdown(); return rv.ErrorCode(); Loading @@ -56,6 +66,11 @@ public: mType = aType; } void SetFailed() { mFailed = true; } private: uint64_t mImgSize; nsAutoString mType; Loading @@ -63,6 +78,7 @@ private: nsCOMPtr<nsIScriptContext> mScriptContext; nsCOMPtr<nsIThread> mEncoderThread; nsRefPtr<FileCallback> mCallback; bool mFailed; }; NS_IMPL_ISUPPORTS1(EncodingCompleteEvent, nsIRunnable); Loading Loading @@ -91,7 +107,7 @@ public: {} virtual ~EncodingRunnable() {} NS_IMETHOD Run() nsresult ProcessImageData(uint64_t* aImgSize, void** aImgData) { nsCOMPtr<nsIInputStream> stream; nsresult rv = ImageEncoder::ExtractDataInternal(mType, Loading @@ -117,18 +133,33 @@ public: } NS_ENSURE_SUCCESS(rv, rv); uint64_t imgSize; rv = stream->Available(&imgSize); rv = stream->Available(aImgSize); NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_TRUE(imgSize <= UINT32_MAX, NS_ERROR_FILE_TOO_BIG); NS_ENSURE_TRUE(*aImgSize <= UINT32_MAX, NS_ERROR_FILE_TOO_BIG); void* imgData = nullptr; rv = NS_ReadInputStreamToBuffer(stream, &imgData, imgSize); rv = NS_ReadInputStreamToBuffer(stream, aImgData, *aImgSize); NS_ENSURE_SUCCESS(rv, rv); return rv; } NS_IMETHOD Run() { uint64_t imgSize; void* imgData = nullptr; nsresult rv = ProcessImageData(&imgSize, &imgData); if (NS_FAILED(rv)) { mEncodingCompleteEvent->SetFailed(); } else { mEncodingCompleteEvent->SetMembers(imgData, imgSize, mType); } rv = NS_DispatchToMainThread(mEncodingCompleteEvent, NS_DISPATCH_NORMAL); NS_ENSURE_SUCCESS(rv, rv); if (NS_FAILED(rv)) { // Better to leak than to crash. mEncodingCompleteEvent.forget(); return rv; } return rv; } Loading