SessionStorageService.cpp (3556B)
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 file, 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "SessionStorageService.h" 8 9 #include "MainThreadUtils.h" 10 #include "mozilla/ClearOnShutdown.h" 11 #include "mozilla/Components.h" 12 #include "mozilla/StaticPtr.h" 13 #include "mozilla/ipc/BackgroundChild.h" 14 #include "mozilla/ipc/PBackgroundChild.h" 15 16 namespace mozilla::dom { 17 18 using namespace mozilla::ipc; 19 20 namespace { 21 22 StaticRefPtr<SessionStorageService> gSessionStorageService; 23 24 bool gShutdown(false); 25 26 } // namespace 27 28 NS_IMPL_ISUPPORTS(SessionStorageService, nsISessionStorageService) 29 30 NS_IMETHODIMP 31 SessionStorageService::ClearStoragesForOrigin(nsIPrincipal* aPrincipal) { 32 AssertIsOnMainThread(); 33 MOZ_ASSERT(aPrincipal); 34 35 QM_TRY_INSPECT(const auto& originAttrs, 36 MOZ_TO_RESULT_INVOKE_MEMBER_TYPED(nsCString, aPrincipal, 37 GetOriginSuffix)); 38 39 QM_TRY_INSPECT(const auto& originKey, 40 MOZ_TO_RESULT_INVOKE_MEMBER_TYPED(nsCString, aPrincipal, 41 GetStorageOriginKey)); 42 43 QM_TRY(OkIf(SendClearStoragesForOrigin(originAttrs, originKey)), 44 NS_ERROR_FAILURE); 45 46 return NS_OK; 47 } 48 49 SessionStorageService::SessionStorageService() { AssertIsOnMainThread(); } 50 51 SessionStorageService::~SessionStorageService() { 52 AssertIsOnMainThread(); 53 MOZ_ASSERT_IF(mInitialized, mActorDestroyed); 54 } 55 56 // static 57 Result<RefPtr<SessionStorageService>, nsresult> SessionStorageService::Acquire( 58 const CreateIfNonExistent&) { 59 AssertIsOnMainThread(); 60 61 QM_TRY(OkIf(!gShutdown), Err(NS_ERROR_ILLEGAL_DURING_SHUTDOWN)); 62 63 if (gSessionStorageService) { 64 return RefPtr<SessionStorageService>(gSessionStorageService); 65 } 66 67 auto sessionStorageService = MakeRefPtr<SessionStorageService>(); 68 69 QM_TRY(sessionStorageService->Init()); 70 71 gSessionStorageService = sessionStorageService; 72 73 RunOnShutdown( 74 [] { 75 gShutdown = true; 76 77 gSessionStorageService->Shutdown(); 78 79 gSessionStorageService = nullptr; 80 }, 81 ShutdownPhase::XPCOMShutdown); 82 83 return sessionStorageService; 84 } 85 86 // static 87 RefPtr<SessionStorageService> SessionStorageService::Acquire() { 88 AssertIsOnMainThread(); 89 90 return gSessionStorageService; 91 } 92 93 Result<Ok, nsresult> SessionStorageService::Init() { 94 AssertIsOnMainThread(); 95 96 PBackgroundChild* backgroundActor = 97 BackgroundChild::GetOrCreateForCurrentThread(); 98 QM_TRY(OkIf(backgroundActor), Err(NS_ERROR_FAILURE)); 99 100 QM_TRY(OkIf(backgroundActor->SendPBackgroundSessionStorageServiceConstructor( 101 this)), 102 Err(NS_ERROR_FAILURE)); 103 104 mInitialized.Flip(); 105 106 return Ok{}; 107 } 108 109 void SessionStorageService::Shutdown() { 110 AssertIsOnMainThread(); 111 112 if (!mActorDestroyed) { 113 QM_WARNONLY_TRY(OkIf(Send__delete__(this))); 114 } 115 } 116 117 void SessionStorageService::ActorDestroy(ActorDestroyReason /* aWhy */) { 118 AssertIsOnMainThread(); 119 120 mActorDestroyed.Flip(); 121 } 122 123 } // namespace mozilla::dom 124 125 NS_IMPL_COMPONENT_FACTORY(nsISessionStorageService) { 126 mozilla::AssertIsOnMainThread(); 127 128 QM_TRY_UNWRAP(auto sessionStorageService, 129 mozilla::dom::SessionStorageService::Acquire( 130 mozilla::CreateIfNonExistent{}), 131 nullptr); 132 133 return sessionStorageService.forget().downcast<nsISupports>(); 134 }