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