UniversalDirectoryLock.cpp (3032B)
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 "UniversalDirectoryLock.h" 8 9 #include <utility> 10 11 #include "mozilla/Assertions.h" 12 #include "mozilla/NotNull.h" 13 #include "mozilla/RefPtr.h" 14 #include "mozilla/ReverseIterator.h" 15 #include "mozilla/dom/Nullable.h" 16 #include "mozilla/dom/quota/ClientDirectoryLock.h" 17 #include "mozilla/dom/quota/CommonMetadata.h" 18 #include "mozilla/dom/quota/OriginScope.h" 19 #include "mozilla/dom/quota/PersistenceScope.h" 20 #include "mozilla/dom/quota/QuotaManager.h" 21 #include "nsDebug.h" 22 #include "nsString.h" 23 24 namespace mozilla::dom::quota { 25 26 RefPtr<ClientDirectoryLock> UniversalDirectoryLock::SpecializeForClient( 27 PersistenceType aPersistenceType, 28 const quota::OriginMetadata& aOriginMetadata, 29 Client::Type aClientType) const { 30 AssertIsOnOwningThread(); 31 MOZ_ASSERT(aPersistenceType != PERSISTENCE_TYPE_INVALID); 32 MOZ_ASSERT(!aOriginMetadata.mGroup.IsEmpty()); 33 MOZ_ASSERT(!aOriginMetadata.mOrigin.IsEmpty()); 34 MOZ_ASSERT(aClientType < Client::TypeMax()); 35 MOZ_ASSERT(mAcquirePromiseHolder.IsEmpty()); 36 MOZ_ASSERT(mBlockedOn.IsEmpty()); 37 38 if (NS_WARN_IF(mExclusive)) { 39 return nullptr; 40 } 41 42 RefPtr<ClientDirectoryLock> lock = ClientDirectoryLock::Create( 43 mQuotaManager, PersistenceScope::CreateFromValue(aPersistenceType), 44 OriginScope::FromOrigin(aOriginMetadata), 45 ClientStorageScope::CreateFromClient(aClientType), 46 /* aExclusive */ false, mInternal, ShouldUpdateLockIdTableFlag::Yes, 47 mCategory); 48 if (NS_WARN_IF(!Overlaps(*lock))) { 49 return nullptr; 50 } 51 52 #ifdef DEBUG 53 for (DirectoryLockImpl* const existingLock : 54 Reversed(mQuotaManager->mDirectoryLocks)) { 55 if (existingLock != this && !existingLock->MustWaitFor(*this)) { 56 MOZ_ASSERT(!existingLock->MustWaitFor(*lock)); 57 } 58 } 59 #endif 60 61 for (const auto& blockedLock : mBlocking) { 62 if (blockedLock->MustWaitFor(*lock)) { 63 lock->AddBlockingLock(*blockedLock); 64 blockedLock->AddBlockedOnLock(*lock); 65 } 66 } 67 68 mQuotaManager->RegisterDirectoryLock(*lock); 69 70 if (mInvalidated) { 71 lock->Invalidate(); 72 } 73 74 return lock; 75 } 76 77 // static 78 RefPtr<UniversalDirectoryLock> UniversalDirectoryLock::CreateInternal( 79 MovingNotNull<RefPtr<QuotaManager>> aQuotaManager, 80 const PersistenceScope& aPersistenceScope, const OriginScope& aOriginScope, 81 const ClientStorageScope& aClientStorageScope, bool aExclusive, 82 DirectoryLockCategory aCategory) { 83 MOZ_ASSERT_IF(aOriginScope.IsOrigin(), !aOriginScope.GetOrigin().IsEmpty()); 84 85 return MakeRefPtr<UniversalDirectoryLock>( 86 std::move(aQuotaManager), aPersistenceScope, aOriginScope, 87 aClientStorageScope, aExclusive, true, ShouldUpdateLockIdTableFlag::Yes, 88 aCategory); 89 } 90 91 } // namespace mozilla::dom::quota