tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

FileSystemManagerChild.cpp (4690B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "FileSystemManagerChild.h"
      8 
      9 #include "FileSystemAccessHandleChild.h"
     10 #include "FileSystemBackgroundRequestHandler.h"
     11 #include "FileSystemWritableFileStreamChild.h"
     12 #include "mozilla/dom/FileSystemSyncAccessHandle.h"
     13 #include "mozilla/dom/FileSystemWritableFileStream.h"
     14 
     15 namespace mozilla::dom {
     16 
     17 void FileSystemManagerChild::SetBackgroundRequestHandler(
     18    FileSystemBackgroundRequestHandler* aBackgroundRequestHandler) {
     19  MOZ_ASSERT(aBackgroundRequestHandler);
     20  MOZ_ASSERT(!mBackgroundRequestHandler);
     21 
     22  mBackgroundRequestHandler = aBackgroundRequestHandler;
     23 }
     24 
     25 void FileSystemManagerChild::CloseAllWritables(
     26    std::function<void()>&& aCallback) {
     27  nsTArray<RefPtr<BoolPromise>> promises;
     28  CloseAllWritablesImpl(promises);
     29 
     30  // FileSystemManagerChild::CloseAllWritables is sometimes called from
     31  // FileSystemManager::Shutdown which can be called late in app shutdown
     32  // when GetCurrentSerialEventTarget returns null. At that point there
     33  // are no writable file streams. The problem with GetCurrentSerialEventTarget
     34  // returning null can be solved by calling the callback directly without
     35  // dispatching a new runnable.
     36  if (promises.IsEmpty()) {
     37    aCallback();
     38    return;
     39  }
     40 
     41  BoolPromise::AllSettled(GetCurrentSerialEventTarget(), promises)
     42      ->Then(GetCurrentSerialEventTarget(), __func__,
     43             [callback = std::move(aCallback)](
     44                 const BoolPromise::AllSettledPromiseType::ResolveOrRejectValue&
     45                 /* aValues */) { callback(); });
     46 }
     47 
     48 #ifdef DEBUG
     49 bool FileSystemManagerChild::AllSyncAccessHandlesClosed() const {
     50  for (const auto& item : ManagedPFileSystemAccessHandleChild()) {
     51    auto* child = static_cast<FileSystemAccessHandleChild*>(item);
     52    auto* handle = child->MutableAccessHandlePtr();
     53 
     54    if (!handle->IsClosed()) {
     55      return false;
     56    }
     57  }
     58 
     59  return true;
     60 }
     61 
     62 bool FileSystemManagerChild::AllWritableFileStreamsClosed() const {
     63  for (const auto& item : ManagedPFileSystemWritableFileStreamChild()) {
     64    auto* const child = static_cast<FileSystemWritableFileStreamChild*>(item);
     65    auto* const handle = child->MutableWritableFileStreamPtr();
     66    if (!handle) {
     67      continue;
     68    }
     69 
     70    if (!handle->IsDone()) {
     71      return false;
     72    }
     73  }
     74 
     75  return true;
     76 }
     77 
     78 #endif
     79 
     80 void FileSystemManagerChild::Shutdown() {
     81  if (!CanSend()) {
     82    return;
     83  }
     84 
     85  Close();
     86 }
     87 
     88 already_AddRefed<PFileSystemWritableFileStreamChild>
     89 FileSystemManagerChild::AllocPFileSystemWritableFileStreamChild() {
     90  return MakeAndAddRef<FileSystemWritableFileStreamChild>();
     91 }
     92 
     93 ::mozilla::ipc::IPCResult FileSystemManagerChild::RecvCloseAll(
     94    CloseAllResolver&& aResolver) {
     95  mCloseAllReceived = true;
     96 
     97  nsTArray<RefPtr<BoolPromise>> promises;
     98 
     99  // NOTE: getFile() creates blobs that read the data from the child;
    100  // we'll need to abort any reads and resolve this call only when all
    101  // blobs are closed.
    102 
    103  for (const auto& item : ManagedPFileSystemAccessHandleChild()) {
    104    auto* child = static_cast<FileSystemAccessHandleChild*>(item);
    105    auto* handle = child->MutableAccessHandlePtr();
    106 
    107    if (handle->IsOpen()) {
    108      promises.AppendElement(handle->BeginClose());
    109    } else if (handle->IsClosing()) {
    110      promises.AppendElement(handle->OnClose());
    111    }
    112  }
    113 
    114  CloseAllWritablesImpl(promises);
    115 
    116  BoolPromise::AllSettled(GetCurrentSerialEventTarget(), promises)
    117      ->Then(GetCurrentSerialEventTarget(), __func__,
    118             [resolver = std::move(aResolver)](
    119                 const BoolPromise::AllSettledPromiseType::ResolveOrRejectValue&
    120                 /* aValues */) { resolver(NS_OK); });
    121 
    122  return IPC_OK();
    123 }
    124 
    125 void FileSystemManagerChild::ActorDestroy(ActorDestroyReason aWhy) {
    126  if (mBackgroundRequestHandler) {
    127    mBackgroundRequestHandler->ClearActor();
    128    mBackgroundRequestHandler = nullptr;
    129  }
    130 }
    131 
    132 template <class T>
    133 void FileSystemManagerChild::CloseAllWritablesImpl(T& aPromises) {
    134  for (const auto& item : ManagedPFileSystemWritableFileStreamChild()) {
    135    auto* const child = static_cast<FileSystemWritableFileStreamChild*>(item);
    136    auto* const handle = child->MutableWritableFileStreamPtr();
    137 
    138    if (handle) {
    139      if (handle->IsOpen()) {
    140        aPromises.AppendElement(handle->BeginAbort());
    141      } else if (handle->IsFinishing()) {
    142        aPromises.AppendElement(handle->OnDone());
    143      }
    144    }
    145  }
    146 }
    147 
    148 }  // namespace mozilla::dom