зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1769878, ensure objects owned by the worker thread are cleared when the worker is shutting down, r=asuth,aosmond
Depends on D147858 Differential Revision: https://phabricator.services.mozilla.com/D149693
This commit is contained in:
Родитель
f6d26b044a
Коммит
e90bd7f443
|
@ -125,6 +125,11 @@ class EncodingCompleteEvent final : public DiscardableRunnable {
|
|||
return mCreationEventTarget;
|
||||
}
|
||||
|
||||
bool CanBeDeletedOnAnyThread() {
|
||||
return !mEncodeCompleteCallback ||
|
||||
mEncodeCompleteCallback->CanBeDeletedOnAnyThread();
|
||||
}
|
||||
|
||||
private:
|
||||
uint64_t mImgSize;
|
||||
nsAutoString mType;
|
||||
|
@ -192,8 +197,10 @@ class EncodingRunnable : public Runnable {
|
|||
rv = mEncodingCompleteEvent->GetCreationThreadEventTarget()->Dispatch(
|
||||
mEncodingCompleteEvent, nsIThread::DISPATCH_NORMAL);
|
||||
if (NS_FAILED(rv)) {
|
||||
// Better to leak than to crash.
|
||||
Unused << mEncodingCompleteEvent.forget();
|
||||
if (!mEncodingCompleteEvent->CanBeDeletedOnAnyThread()) {
|
||||
// Better to leak than to crash.
|
||||
Unused << mEncodingCompleteEvent.forget();
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
|
@ -111,6 +111,11 @@ class EncodeCompleteCallback {
|
|||
MOZ_CAN_RUN_SCRIPT
|
||||
virtual nsresult ReceiveBlobImpl(already_AddRefed<BlobImpl> aBlobImpl) = 0;
|
||||
|
||||
// CanBeDeletedOnAnyThread is pure virtual, so that whoever extends this class
|
||||
// needs to think how to handle cases like the owning DOM worker thread
|
||||
// shutting down.
|
||||
virtual bool CanBeDeletedOnAnyThread() = 0;
|
||||
|
||||
protected:
|
||||
virtual ~EncodeCompleteCallback() = default;
|
||||
};
|
||||
|
|
|
@ -39,6 +39,8 @@ void CanvasRenderingContextHelper::ToBlob(
|
|||
// This is called on main thread.
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
nsresult ReceiveBlobImpl(already_AddRefed<BlobImpl> aBlobImpl) override {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
RefPtr<BlobImpl> blobImpl = aBlobImpl;
|
||||
|
||||
RefPtr<Blob> blob;
|
||||
|
@ -58,6 +60,11 @@ void CanvasRenderingContextHelper::ToBlob(
|
|||
return rv.StealNSResult();
|
||||
}
|
||||
|
||||
bool CanBeDeletedOnAnyThread() override {
|
||||
// EncodeCallback is used from the main thread only.
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIGlobalObject> mGlobal;
|
||||
RefPtr<BlobCallback> mBlobCallback;
|
||||
};
|
||||
|
|
|
@ -6,12 +6,14 @@
|
|||
|
||||
#include "OffscreenCanvas.h"
|
||||
|
||||
#include "mozilla/Atomics.h"
|
||||
#include "mozilla/dom/BlobImpl.h"
|
||||
#include "mozilla/dom/OffscreenCanvasBinding.h"
|
||||
#include "mozilla/dom/OffscreenCanvasDisplayHelper.h"
|
||||
#include "mozilla/dom/OffscreenCanvasRenderingContext2D.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/dom/WorkerPrivate.h"
|
||||
#include "mozilla/dom/WorkerRef.h"
|
||||
#include "mozilla/dom/WorkerScope.h"
|
||||
#include "mozilla/layers/ImageBridgeChild.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
|
@ -277,11 +279,21 @@ OffscreenCanvas::CreateEncodeCompleteCallback(Promise* aPromise) {
|
|||
// Encoder callback when encoding is complete.
|
||||
class EncodeCallback : public EncodeCompleteCallback {
|
||||
public:
|
||||
explicit EncodeCallback(Promise* aPromise) : mPromise(aPromise) {}
|
||||
explicit EncodeCallback(Promise* aPromise)
|
||||
: mPromise(aPromise), mCanceled(false) {
|
||||
WorkerPrivate* wp = GetCurrentThreadWorkerPrivate();
|
||||
if (wp) {
|
||||
mWorkerRef = WeakWorkerRef::Create(
|
||||
wp, [self = RefPtr{this}]() { self->Cancel(); });
|
||||
if (!mWorkerRef) {
|
||||
Cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This is called on main thread.
|
||||
nsresult ReceiveBlobImpl(already_AddRefed<BlobImpl> aBlobImpl) override {
|
||||
RefPtr<BlobImpl> blobImpl = aBlobImpl;
|
||||
mWorkerRef = nullptr;
|
||||
|
||||
if (mPromise) {
|
||||
RefPtr<nsIGlobalObject> global = mPromise->GetGlobalObject();
|
||||
|
@ -302,7 +314,17 @@ OffscreenCanvas::CreateEncodeCompleteCallback(Promise* aPromise) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
bool CanBeDeletedOnAnyThread() override { return mCanceled; }
|
||||
|
||||
void Cancel() {
|
||||
mPromise = nullptr;
|
||||
mWorkerRef = nullptr;
|
||||
mCanceled = true;
|
||||
}
|
||||
|
||||
RefPtr<Promise> mPromise;
|
||||
RefPtr<WeakWorkerRef> mWorkerRef;
|
||||
Atomic<bool> mCanceled;
|
||||
};
|
||||
|
||||
return MakeAndAddRef<EncodeCallback>(aPromise);
|
||||
|
|
|
@ -110,8 +110,14 @@ void CaptureTask::NotifyRealtimeTrackData(MediaTrackGraph* aGraph,
|
|||
public:
|
||||
explicit EncodeComplete(CaptureTask* aTask) : mTask(aTask) {}
|
||||
|
||||
bool CanBeDeletedOnAnyThread() override {
|
||||
// EncodeComplete is used from the main thread only.
|
||||
return false;
|
||||
}
|
||||
|
||||
nsresult ReceiveBlobImpl(
|
||||
already_AddRefed<dom::BlobImpl> aBlobImpl) override {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
RefPtr<dom::BlobImpl> blobImpl(aBlobImpl);
|
||||
mTask->TaskComplete(blobImpl.forget(), NS_OK);
|
||||
mTask = nullptr;
|
||||
|
|
Загрузка…
Ссылка в новой задаче