150 lines
5.2 KiB
C++
150 lines
5.2 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include "FileSystemBackgroundRequestHandler.h"
|
|
|
|
#include "fs/FileSystemChildFactory.h"
|
|
#include "mozilla/dom/FileSystemManagerChild.h"
|
|
#include "mozilla/dom/PFileSystemManager.h"
|
|
#include "mozilla/ipc/BackgroundChild.h"
|
|
#include "mozilla/ipc/Endpoint.h"
|
|
#include "mozilla/ipc/PBackgroundChild.h"
|
|
|
|
namespace mozilla::dom {
|
|
|
|
FileSystemBackgroundRequestHandler::FileSystemBackgroundRequestHandler(
|
|
fs::FileSystemChildFactory* aChildFactory)
|
|
: mChildFactory(aChildFactory), mCreatingFileSystemManagerChild(false) {}
|
|
|
|
FileSystemBackgroundRequestHandler::FileSystemBackgroundRequestHandler(
|
|
RefPtr<FileSystemManagerChild> aFileSystemManagerChild)
|
|
: mFileSystemManagerChild(std::move(aFileSystemManagerChild)),
|
|
mCreatingFileSystemManagerChild(false) {}
|
|
|
|
FileSystemBackgroundRequestHandler::FileSystemBackgroundRequestHandler()
|
|
: FileSystemBackgroundRequestHandler(new fs::FileSystemChildFactory()) {}
|
|
|
|
FileSystemBackgroundRequestHandler::~FileSystemBackgroundRequestHandler() =
|
|
default;
|
|
|
|
void FileSystemBackgroundRequestHandler::ClearActor() {
|
|
MOZ_ASSERT(mFileSystemManagerChild);
|
|
|
|
mFileSystemManagerChild = nullptr;
|
|
}
|
|
|
|
void FileSystemBackgroundRequestHandler::Shutdown() {
|
|
mShutdown.Flip();
|
|
|
|
if (mFileSystemManagerChild) {
|
|
MOZ_ASSERT(!mCreatingFileSystemManagerChild);
|
|
|
|
mFileSystemManagerChild->Shutdown();
|
|
|
|
mFileSystemManagerChild = nullptr;
|
|
|
|
return;
|
|
}
|
|
|
|
if (mCreatingFileSystemManagerChild) {
|
|
MOZ_ASSERT(!mFileSystemManagerChild);
|
|
|
|
mCreateFileSystemManagerParentPromiseRequestHolder.Disconnect();
|
|
|
|
mCreatingFileSystemManagerChild = false;
|
|
|
|
// We must either resolve/reject the promise or steal the internal promise
|
|
// before the holder is destroyed. The former isn't possible during
|
|
// shutdown.
|
|
Unused << mCreateFileSystemManagerChildPromiseHolder.Steal();
|
|
}
|
|
}
|
|
|
|
const RefPtr<FileSystemManagerChild>&
|
|
FileSystemBackgroundRequestHandler::FileSystemManagerChildStrongRef() const {
|
|
return mFileSystemManagerChild;
|
|
}
|
|
|
|
RefPtr<FileSystemManagerChild::ActorPromise>
|
|
FileSystemBackgroundRequestHandler::CreateFileSystemManagerChild(
|
|
const mozilla::ipc::PrincipalInfo& aPrincipalInfo) {
|
|
MOZ_ASSERT(!mFileSystemManagerChild);
|
|
MOZ_ASSERT(!mShutdown);
|
|
|
|
using mozilla::ipc::BackgroundChild;
|
|
using mozilla::ipc::Endpoint;
|
|
using mozilla::ipc::PBackgroundChild;
|
|
|
|
if (!mCreatingFileSystemManagerChild) {
|
|
PBackgroundChild* backgroundChild =
|
|
BackgroundChild::GetOrCreateForCurrentThread();
|
|
if (NS_WARN_IF(!backgroundChild)) {
|
|
return FileSystemManagerChild::ActorPromise::CreateAndReject(
|
|
NS_ERROR_FAILURE, __func__);
|
|
}
|
|
|
|
// Create a new IPC connection
|
|
Endpoint<PFileSystemManagerParent> parentEndpoint;
|
|
Endpoint<PFileSystemManagerChild> childEndpoint;
|
|
MOZ_ALWAYS_SUCCEEDS(
|
|
PFileSystemManager::CreateEndpoints(&parentEndpoint, &childEndpoint));
|
|
|
|
RefPtr<FileSystemManagerChild> child = mChildFactory->Create();
|
|
if (!childEndpoint.Bind(child)) {
|
|
return FileSystemManagerChild::ActorPromise::CreateAndReject(
|
|
NS_ERROR_FAILURE, __func__);
|
|
}
|
|
|
|
mCreatingFileSystemManagerChild = true;
|
|
|
|
backgroundChild
|
|
->SendCreateFileSystemManagerParent(aPrincipalInfo,
|
|
std::move(parentEndpoint))
|
|
->Then(
|
|
GetCurrentSerialEventTarget(), __func__,
|
|
[self = RefPtr<FileSystemBackgroundRequestHandler>(this),
|
|
child](nsresult rv) mutable {
|
|
self->mCreateFileSystemManagerParentPromiseRequestHolder
|
|
.Complete();
|
|
|
|
self->mCreatingFileSystemManagerChild = false;
|
|
|
|
if (child->CloseAllReceived()) {
|
|
self->mCreateFileSystemManagerChildPromiseHolder.RejectIfExists(
|
|
NS_ERROR_ABORT, __func__);
|
|
return;
|
|
}
|
|
|
|
if (NS_FAILED(rv)) {
|
|
self->mCreateFileSystemManagerChildPromiseHolder.RejectIfExists(
|
|
rv, __func__);
|
|
} else {
|
|
self->mFileSystemManagerChild = child;
|
|
|
|
self->mFileSystemManagerChild->SetBackgroundRequestHandler(
|
|
self);
|
|
|
|
self->mCreateFileSystemManagerChildPromiseHolder
|
|
.ResolveIfExists(std::move(child), __func__);
|
|
}
|
|
},
|
|
[self = RefPtr<FileSystemBackgroundRequestHandler>(this)](
|
|
const mozilla::ipc::ResponseRejectReason&) {
|
|
self->mCreateFileSystemManagerParentPromiseRequestHolder
|
|
.Complete();
|
|
|
|
self->mCreatingFileSystemManagerChild = false;
|
|
|
|
self->mCreateFileSystemManagerChildPromiseHolder.RejectIfExists(
|
|
NS_ERROR_FAILURE, __func__);
|
|
})
|
|
->Track(mCreateFileSystemManagerParentPromiseRequestHolder);
|
|
}
|
|
|
|
return mCreateFileSystemManagerChildPromiseHolder.Ensure(__func__);
|
|
}
|
|
|
|
} // namespace mozilla::dom
|