Commit 8404d250 authored by Jan Varga's avatar Jan Varga
Browse files

Bug 1856072 - Add proper handling for failed worker refs; r=#dom-storage a=dsmith

parent a862174a
Loading
Loading
Loading
Loading
+74 −66
Original line number Diff line number Diff line
@@ -295,7 +295,8 @@ FileSystemWritableFileStream::Create(
    RefPtr<FileSystemManager>& aManager,
    RefPtr<FileSystemWritableFileStreamChild> aActor,
    mozilla::ipc::RandomAccessStreamParams&& aStreamParams,
    fs::FileSystemEntryMetadata&& aMetadata) {
    fs::FileSystemEntryMetadata&& aMetadata,
    RefPtr<StrongWorkerRef> aBuildWorkerRef) {
  using StreamPromise = MozPromise<NotNull<nsCOMPtr<nsIRandomAccessStream>>,
                                   nsresult, /* IsExclusive */ true>;

@@ -313,11 +314,11 @@ FileSystemWritableFileStream::Create(
      TaskQueue::Create(streamTransportService.forget(), "WritableStreamQueue");
  MOZ_ASSERT(taskQueue);

  auto streamSetup =
      [aGlobal, aManager, actor = std::move(aActor), taskQueue,
       metadata =
           std::move(aMetadata)](StreamPromise::ResolveOrRejectValue&& aValue)
          MOZ_CAN_RUN_SCRIPT mutable {
  auto streamSetup = [aGlobal, aManager, actor = std::move(aActor), taskQueue,
                      metadata = std::move(aMetadata),
                      buildWorkerRef = std::move(aBuildWorkerRef)](
                         StreamPromise::ResolveOrRejectValue&&
                             aValue) MOZ_CAN_RUN_SCRIPT mutable {
    auto rejectAndReturn = [](const nsresult aRv) {
      return CreatePromise::CreateAndReject(aRv, __func__);
    };
@@ -338,19 +339,31 @@ FileSystemWritableFileStream::Create(

    // Step 5. Perform ! InitializeWritableStream(stream).
    // (Done by the constructor)
            nsCOMPtr<nsIRandomAccessStream> inputOutputStream =
                aValue.ResolveValue();
    nsCOMPtr<nsIRandomAccessStream> inputOutputStream = aValue.ResolveValue();
    RefPtr<FileSystemWritableFileStream> stream =
        new FileSystemWritableFileStream(
            aGlobal, aManager, std::move(actor), taskQueue.forget(),
                    /* random access stream */ inputOutputStream,
                    std::move(metadata));
            /* random access stream */ inputOutputStream, std::move(metadata));

    auto autoClose = MakeScopeExit([stream] {
      stream->mCloseHandler->Close();
      stream->mActor->SendClose();
    });

    RefPtr<StrongWorkerRef> workerRef;
    if (buildWorkerRef) {
      workerRef =
          StrongWorkerRef::Create(buildWorkerRef->Private(),
                                  "FileSystemWritableFileStream", [stream]() {
                                    if (stream->IsOpen()) {
                                      // We don't need the promise, we just
                                      // begin the closing process.
                                      Unused << stream->BeginClose();
                                    }
                                  });
      QM_TRY(MOZ_TO_RESULT(workerRef), rejectAndReturn);
    }

    // Step 3 - 5
    auto algorithms =
        MakeRefPtr<WritableFileStreamUnderlyingSinkAlgorithms>(*stream);
@@ -368,11 +381,11 @@ FileSystemWritableFileStream::Create(
                        // WritableStream::Constructor for details)
                        nullptr, rv);
    if (rv.Failed()) {
              return CreatePromise::CreateAndReject(rv.StealNSResult(),
                                                    __func__);
      return CreatePromise::CreateAndReject(rv.StealNSResult(), __func__);
    }

    autoClose.release();
    stream->mWorkerRef = std::move(workerRef);
    stream->mCloseHandler->Open();

    // Step 9: Return stream.
@@ -497,11 +510,6 @@ RefPtr<BoolPromise> FileSystemWritableFileStream::BeginClose() {
  return mCloseHandler->GetClosePromise();
}

void FileSystemWritableFileStream::SetWorkerRef(
    RefPtr<StrongWorkerRef>&& aWorkerRef) {
  mWorkerRef = std::move(aWorkerRef);
}

already_AddRefed<Promise> FileSystemWritableFileStream::Write(
    JSContext* aCx, JS::Handle<JS::Value> aChunk, ErrorResult& aError) {
  // https://fs.spec.whatwg.org/#create-a-new-filesystemwritablefilestream
+2 −3
Original line number Diff line number Diff line
@@ -53,7 +53,8 @@ class FileSystemWritableFileStream final : public WritableStream {
      RefPtr<FileSystemManager>& aManager,
      RefPtr<FileSystemWritableFileStreamChild> aActor,
      mozilla::ipc::RandomAccessStreamParams&& aStreamParams,
      fs::FileSystemEntryMetadata&& aMetadata);
      fs::FileSystemEntryMetadata&& aMetadata,
      RefPtr<StrongWorkerRef> aBuildWorkerRef);

  NS_DECL_ISUPPORTS_INHERITED
  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(FileSystemWritableFileStream,
@@ -74,8 +75,6 @@ class FileSystemWritableFileStream final : public WritableStream {

  [[nodiscard]] RefPtr<BoolPromise> BeginClose();

  void SetWorkerRef(RefPtr<StrongWorkerRef>&& aWorkerRef);

  already_AddRefed<Promise> Write(JSContext* aCx, JS::Handle<JS::Value> aChunk,
                                  ErrorResult& aError);

+4 −19
Original line number Diff line number Diff line
@@ -280,30 +280,15 @@ void ResolveCallback(FileSystemGetWritableFileStreamResponse&& aResponse,

  autoDelete.release();

  FileSystemWritableFileStream::Create(aPromise->GetParentObject(), aManager,
                                       actor, std::move(params),
                                       std::move(metadata))
  FileSystemWritableFileStream::Create(
      aPromise->GetParentObject(), aManager, actor, std::move(params),
      std::move(metadata), std::move(buildWorkerRef))
      ->Then(GetCurrentSerialEventTarget(), __func__,
             [buildWorkerRef,
              aPromise](CreatePromise::ResolveOrRejectValue&& aValue) {
             [aPromise](CreatePromise::ResolveOrRejectValue&& aValue) {
               if (aValue.IsResolve()) {
                 RefPtr<FileSystemWritableFileStream> stream =
                     aValue.ResolveValue();

                 if (buildWorkerRef) {
                   RefPtr<StrongWorkerRef> workerRef = StrongWorkerRef::Create(
                       buildWorkerRef->Private(),
                       "FileSystemWritableFileStream", [stream]() {
                         if (stream->IsOpen()) {
                           // We don't need the promise, we just begin the
                           // closing process.
                           Unused << stream->BeginClose();
                         }
                       });

                   stream->SetWorkerRef(std::move(workerRef));
                 }

                 aPromise->MaybeResolve(stream);
                 return;
               }
+1 −0
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@ self.onmessage = async function(e) {
    await a.createWritable({})
}
</script>

<script>
window.addEventListener("load", async () => {
    let a = await self.clientInformation.storage.getDirectory()