tor-browser

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

FileSystemBackgroundRequestHandler.cpp (5300B)


      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 "FileSystemBackgroundRequestHandler.h"
      8 
      9 #include "fs/FileSystemChildFactory.h"
     10 #include "mozilla/dom/FileSystemManagerChild.h"
     11 #include "mozilla/dom/PFileSystemManager.h"
     12 #include "mozilla/ipc/BackgroundChild.h"
     13 #include "mozilla/ipc/Endpoint.h"
     14 #include "mozilla/ipc/PBackgroundChild.h"
     15 
     16 namespace mozilla::dom {
     17 
     18 FileSystemBackgroundRequestHandler::FileSystemBackgroundRequestHandler(
     19    fs::FileSystemChildFactory* aChildFactory)
     20    : mChildFactory(aChildFactory), mCreatingFileSystemManagerChild(false) {}
     21 
     22 FileSystemBackgroundRequestHandler::FileSystemBackgroundRequestHandler(
     23    RefPtr<FileSystemManagerChild> aFileSystemManagerChild)
     24    : mFileSystemManagerChild(std::move(aFileSystemManagerChild)),
     25      mCreatingFileSystemManagerChild(false) {}
     26 
     27 FileSystemBackgroundRequestHandler::FileSystemBackgroundRequestHandler()
     28    : FileSystemBackgroundRequestHandler(new fs::FileSystemChildFactory()) {}
     29 
     30 FileSystemBackgroundRequestHandler::~FileSystemBackgroundRequestHandler() =
     31    default;
     32 
     33 void FileSystemBackgroundRequestHandler::ClearActor() {
     34  MOZ_ASSERT(mFileSystemManagerChild);
     35 
     36  mFileSystemManagerChild = nullptr;
     37 }
     38 
     39 void FileSystemBackgroundRequestHandler::Shutdown() {
     40  mShutdown.Flip();
     41 
     42  if (mFileSystemManagerChild) {
     43    MOZ_ASSERT(!mCreatingFileSystemManagerChild);
     44 
     45    mFileSystemManagerChild->Shutdown();
     46 
     47    mFileSystemManagerChild = nullptr;
     48 
     49    return;
     50  }
     51 
     52  if (mCreatingFileSystemManagerChild) {
     53    MOZ_ASSERT(!mFileSystemManagerChild);
     54 
     55    mCreateFileSystemManagerParentPromiseRequestHolder.Disconnect();
     56 
     57    mCreatingFileSystemManagerChild = false;
     58 
     59    // We must either resolve/reject the promise or steal the internal promise
     60    // before the holder is destroyed. The former isn't possible during
     61    // shutdown.
     62    mCreateFileSystemManagerChildPromiseHolder.Steal().leak();
     63  }
     64 }
     65 
     66 const RefPtr<FileSystemManagerChild>&
     67 FileSystemBackgroundRequestHandler::FileSystemManagerChildStrongRef() const {
     68  return mFileSystemManagerChild;
     69 }
     70 
     71 RefPtr<FileSystemManagerChild::ActorPromise>
     72 FileSystemBackgroundRequestHandler::CreateFileSystemManagerChild(
     73    const mozilla::ipc::PrincipalInfo& aPrincipalInfo) {
     74  MOZ_ASSERT(!mFileSystemManagerChild);
     75  MOZ_ASSERT(!mShutdown);
     76 
     77  using mozilla::ipc::BackgroundChild;
     78  using mozilla::ipc::Endpoint;
     79  using mozilla::ipc::PBackgroundChild;
     80 
     81  if (!mCreatingFileSystemManagerChild) {
     82    PBackgroundChild* backgroundChild =
     83        BackgroundChild::GetOrCreateForCurrentThread();
     84    if (NS_WARN_IF(!backgroundChild)) {
     85      return FileSystemManagerChild::ActorPromise::CreateAndReject(
     86          NS_ERROR_FAILURE, __func__);
     87    }
     88 
     89    // Create a new IPC connection
     90    Endpoint<PFileSystemManagerParent> parentEndpoint;
     91    Endpoint<PFileSystemManagerChild> childEndpoint;
     92    MOZ_ALWAYS_SUCCEEDS(
     93        PFileSystemManager::CreateEndpoints(&parentEndpoint, &childEndpoint));
     94 
     95    RefPtr<FileSystemManagerChild> child = mChildFactory->Create();
     96    if (!childEndpoint.Bind(child)) {
     97      return FileSystemManagerChild::ActorPromise::CreateAndReject(
     98          NS_ERROR_FAILURE, __func__);
     99    }
    100 
    101    mCreatingFileSystemManagerChild = true;
    102 
    103    backgroundChild
    104        ->SendCreateFileSystemManagerParent(aPrincipalInfo,
    105                                            std::move(parentEndpoint))
    106        ->Then(
    107            GetCurrentSerialEventTarget(), __func__,
    108            [self = RefPtr<FileSystemBackgroundRequestHandler>(this),
    109             child](nsresult rv) mutable {
    110              self->mCreateFileSystemManagerParentPromiseRequestHolder
    111                  .Complete();
    112 
    113              self->mCreatingFileSystemManagerChild = false;
    114 
    115              if (child->CloseAllReceived()) {
    116                self->mCreateFileSystemManagerChildPromiseHolder.RejectIfExists(
    117                    NS_ERROR_ABORT, __func__);
    118                return;
    119              }
    120 
    121              if (NS_FAILED(rv)) {
    122                self->mCreateFileSystemManagerChildPromiseHolder.RejectIfExists(
    123                    rv, __func__);
    124              } else {
    125                self->mFileSystemManagerChild = child;
    126 
    127                self->mFileSystemManagerChild->SetBackgroundRequestHandler(
    128                    self);
    129 
    130                self->mCreateFileSystemManagerChildPromiseHolder
    131                    .ResolveIfExists(std::move(child), __func__);
    132              }
    133            },
    134            [self = RefPtr<FileSystemBackgroundRequestHandler>(this)](
    135                const mozilla::ipc::ResponseRejectReason&) {
    136              self->mCreateFileSystemManagerParentPromiseRequestHolder
    137                  .Complete();
    138 
    139              self->mCreatingFileSystemManagerChild = false;
    140 
    141              self->mCreateFileSystemManagerChildPromiseHolder.RejectIfExists(
    142                  NS_ERROR_FAILURE, __func__);
    143            })
    144        ->Track(mCreateFileSystemManagerParentPromiseRequestHolder);
    145  }
    146 
    147  return mCreateFileSystemManagerChildPromiseHolder.Ensure(__func__);
    148 }
    149 
    150 }  // namespace mozilla::dom