forked from mirrors/gecko-dev
		
	 384617594d
			
		
	
	
		384617594d
		
	
	
	
	
		
			
			Specifically, instead of using custom loops - use range-based for in QuotaManager::CreateDirectoryLock, QuotaManager::CollectOriginsForEviction, QuotaManager::CollectPendingOriginsForListing, QuotaManager::CheckTemporaryStorageLimits - use range-based for in QuotaManager::RemoveQuota and clear the hashtable after the loop rather than removing individual entries - extract a new overload GroupInfo::LockedRemoveOriginInfo that's called from within the two existing overloads, and use std::find_if resp. range-based for in those overloads - use std::any_of in GetInactiveOriginInfos - use std::is_sorted in GetInactiveOriginInfos - use std::accumulate in QuotaManager::CheckTemporaryStorageLimits - use std::transform in QuotaRequestChild::HandleResponse Differential Revision: https://phabricator.services.mozilla.com/D99790
		
			
				
	
	
		
			383 lines
		
	
	
	
		
			10 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			383 lines
		
	
	
	
		
			10 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 "ActorsChild.h"
 | |
| 
 | |
| // Local includes
 | |
| #include "QuotaManagerService.h"
 | |
| #include "QuotaRequests.h"
 | |
| #include "QuotaResults.h"
 | |
| 
 | |
| // Global includes
 | |
| #include <new>
 | |
| #include <utility>
 | |
| #include "mozilla/Assertions.h"
 | |
| #include "mozilla/dom/quota/PQuotaRequest.h"
 | |
| #include "mozilla/dom/quota/PQuotaUsageRequest.h"
 | |
| #include "nsError.h"
 | |
| #include "nsID.h"
 | |
| #include "nsIEventTarget.h"
 | |
| #include "nsIQuotaResults.h"
 | |
| #include "nsISupports.h"
 | |
| #include "nsIVariant.h"
 | |
| #include "nsString.h"
 | |
| #include "nsThreadUtils.h"
 | |
| #include "nsVariant.h"
 | |
| 
 | |
| namespace mozilla::dom::quota {
 | |
| 
 | |
| /*******************************************************************************
 | |
|  * QuotaChild
 | |
|  ******************************************************************************/
 | |
| 
 | |
| QuotaChild::QuotaChild(QuotaManagerService* aService)
 | |
|     : mService(aService)
 | |
| #ifdef DEBUG
 | |
|       ,
 | |
|       mOwningThread(GetCurrentEventTarget())
 | |
| #endif
 | |
| {
 | |
|   AssertIsOnOwningThread();
 | |
|   MOZ_ASSERT(aService);
 | |
| 
 | |
|   MOZ_COUNT_CTOR(quota::QuotaChild);
 | |
| }
 | |
| 
 | |
| QuotaChild::~QuotaChild() {
 | |
|   AssertIsOnOwningThread();
 | |
| 
 | |
|   MOZ_COUNT_DTOR(quota::QuotaChild);
 | |
| }
 | |
| 
 | |
| #ifdef DEBUG
 | |
| 
 | |
| void QuotaChild::AssertIsOnOwningThread() const {
 | |
|   MOZ_ASSERT(mOwningThread);
 | |
| 
 | |
|   bool current;
 | |
|   MOZ_ASSERT(NS_SUCCEEDED(mOwningThread->IsOnCurrentThread(¤t)));
 | |
|   MOZ_ASSERT(current);
 | |
| }
 | |
| 
 | |
| #endif  // DEBUG
 | |
| 
 | |
| void QuotaChild::ActorDestroy(ActorDestroyReason aWhy) {
 | |
|   AssertIsOnOwningThread();
 | |
| 
 | |
|   if (mService) {
 | |
|     mService->ClearBackgroundActor();
 | |
| #ifdef DEBUG
 | |
|     mService = nullptr;
 | |
| #endif
 | |
|   }
 | |
| }
 | |
| 
 | |
| PQuotaUsageRequestChild* QuotaChild::AllocPQuotaUsageRequestChild(
 | |
|     const UsageRequestParams& aParams) {
 | |
|   AssertIsOnOwningThread();
 | |
| 
 | |
|   MOZ_CRASH("PQuotaUsageRequestChild actors should be manually constructed!");
 | |
| }
 | |
| 
 | |
| bool QuotaChild::DeallocPQuotaUsageRequestChild(
 | |
|     PQuotaUsageRequestChild* aActor) {
 | |
|   AssertIsOnOwningThread();
 | |
|   MOZ_ASSERT(aActor);
 | |
| 
 | |
|   delete static_cast<QuotaUsageRequestChild*>(aActor);
 | |
|   return true;
 | |
| }
 | |
| 
 | |
| PQuotaRequestChild* QuotaChild::AllocPQuotaRequestChild(
 | |
|     const RequestParams& aParams) {
 | |
|   AssertIsOnOwningThread();
 | |
| 
 | |
|   MOZ_CRASH("PQuotaRequestChild actors should be manually constructed!");
 | |
| }
 | |
| 
 | |
| bool QuotaChild::DeallocPQuotaRequestChild(PQuotaRequestChild* aActor) {
 | |
|   AssertIsOnOwningThread();
 | |
|   MOZ_ASSERT(aActor);
 | |
| 
 | |
|   delete static_cast<QuotaRequestChild*>(aActor);
 | |
|   return true;
 | |
| }
 | |
| 
 | |
| /*******************************************************************************
 | |
|  * QuotaUsageRequestChild
 | |
|  ******************************************************************************/
 | |
| 
 | |
| QuotaUsageRequestChild::QuotaUsageRequestChild(UsageRequest* aRequest)
 | |
|     : mRequest(aRequest) {
 | |
|   AssertIsOnOwningThread();
 | |
| 
 | |
|   MOZ_COUNT_CTOR(quota::QuotaUsageRequestChild);
 | |
| }
 | |
| 
 | |
| QuotaUsageRequestChild::~QuotaUsageRequestChild() {
 | |
|   // Can't assert owning thread here because the request is cleared.
 | |
| 
 | |
|   MOZ_COUNT_DTOR(quota::QuotaUsageRequestChild);
 | |
| }
 | |
| 
 | |
| #ifdef DEBUG
 | |
| 
 | |
| void QuotaUsageRequestChild::AssertIsOnOwningThread() const {
 | |
|   MOZ_ASSERT(mRequest);
 | |
|   mRequest->AssertIsOnOwningThread();
 | |
| }
 | |
| 
 | |
| #endif  // DEBUG
 | |
| 
 | |
| void QuotaUsageRequestChild::HandleResponse(nsresult aResponse) {
 | |
|   AssertIsOnOwningThread();
 | |
|   MOZ_ASSERT(NS_FAILED(aResponse));
 | |
|   MOZ_ASSERT(mRequest);
 | |
| 
 | |
|   mRequest->SetError(aResponse);
 | |
| }
 | |
| 
 | |
| void QuotaUsageRequestChild::HandleResponse(
 | |
|     const nsTArray<OriginUsage>& aResponse) {
 | |
|   AssertIsOnOwningThread();
 | |
|   MOZ_ASSERT(mRequest);
 | |
| 
 | |
|   RefPtr<nsVariant> variant = new nsVariant();
 | |
| 
 | |
|   if (aResponse.IsEmpty()) {
 | |
|     variant->SetAsEmptyArray();
 | |
|   } else {
 | |
|     nsTArray<RefPtr<UsageResult>> usageResults(aResponse.Length());
 | |
| 
 | |
|     for (const auto& originUsage : aResponse) {
 | |
|       usageResults.AppendElement(MakeRefPtr<UsageResult>(
 | |
|           originUsage.origin(), originUsage.persisted(), originUsage.usage(),
 | |
|           originUsage.lastAccessed()));
 | |
|     }
 | |
| 
 | |
|     variant->SetAsArray(nsIDataType::VTYPE_INTERFACE_IS,
 | |
|                         &NS_GET_IID(nsIQuotaUsageResult), usageResults.Length(),
 | |
|                         static_cast<void*>(usageResults.Elements()));
 | |
|   }
 | |
| 
 | |
|   mRequest->SetResult(variant);
 | |
| }
 | |
| 
 | |
| void QuotaUsageRequestChild::HandleResponse(
 | |
|     const OriginUsageResponse& aResponse) {
 | |
|   AssertIsOnOwningThread();
 | |
|   MOZ_ASSERT(mRequest);
 | |
| 
 | |
|   RefPtr<OriginUsageResult> result =
 | |
|       new OriginUsageResult(aResponse.usage(), aResponse.fileUsage());
 | |
| 
 | |
|   RefPtr<nsVariant> variant = new nsVariant();
 | |
|   variant->SetAsInterface(NS_GET_IID(nsIQuotaOriginUsageResult), result);
 | |
| 
 | |
|   mRequest->SetResult(variant);
 | |
| }
 | |
| 
 | |
| void QuotaUsageRequestChild::ActorDestroy(ActorDestroyReason aWhy) {
 | |
|   AssertIsOnOwningThread();
 | |
| 
 | |
|   if (mRequest) {
 | |
|     mRequest->ClearBackgroundActor();
 | |
| #ifdef DEBUG
 | |
|     mRequest = nullptr;
 | |
| #endif
 | |
|   }
 | |
| }
 | |
| 
 | |
| mozilla::ipc::IPCResult QuotaUsageRequestChild::Recv__delete__(
 | |
|     const UsageRequestResponse& aResponse) {
 | |
|   AssertIsOnOwningThread();
 | |
|   MOZ_ASSERT(mRequest);
 | |
| 
 | |
|   switch (aResponse.type()) {
 | |
|     case UsageRequestResponse::Tnsresult:
 | |
|       HandleResponse(aResponse.get_nsresult());
 | |
|       break;
 | |
| 
 | |
|     case UsageRequestResponse::TAllUsageResponse:
 | |
|       HandleResponse(aResponse.get_AllUsageResponse().originUsages());
 | |
|       break;
 | |
| 
 | |
|     case UsageRequestResponse::TOriginUsageResponse:
 | |
|       HandleResponse(aResponse.get_OriginUsageResponse());
 | |
|       break;
 | |
| 
 | |
|     default:
 | |
|       MOZ_CRASH("Unknown response type!");
 | |
|   }
 | |
| 
 | |
|   return IPC_OK();
 | |
| }
 | |
| 
 | |
| /*******************************************************************************
 | |
|  * QuotaRequestChild
 | |
|  ******************************************************************************/
 | |
| 
 | |
| QuotaRequestChild::QuotaRequestChild(Request* aRequest) : mRequest(aRequest) {
 | |
|   AssertIsOnOwningThread();
 | |
| 
 | |
|   MOZ_COUNT_CTOR(quota::QuotaRequestChild);
 | |
| }
 | |
| 
 | |
| QuotaRequestChild::~QuotaRequestChild() {
 | |
|   AssertIsOnOwningThread();
 | |
| 
 | |
|   MOZ_COUNT_DTOR(quota::QuotaRequestChild);
 | |
| }
 | |
| 
 | |
| #ifdef DEBUG
 | |
| 
 | |
| void QuotaRequestChild::AssertIsOnOwningThread() const {
 | |
|   MOZ_ASSERT(mRequest);
 | |
|   mRequest->AssertIsOnOwningThread();
 | |
| }
 | |
| 
 | |
| #endif  // DEBUG
 | |
| 
 | |
| void QuotaRequestChild::HandleResponse(nsresult aResponse) {
 | |
|   AssertIsOnOwningThread();
 | |
|   MOZ_ASSERT(NS_FAILED(aResponse));
 | |
|   MOZ_ASSERT(mRequest);
 | |
| 
 | |
|   mRequest->SetError(aResponse);
 | |
| }
 | |
| 
 | |
| void QuotaRequestChild::HandleResponse() {
 | |
|   AssertIsOnOwningThread();
 | |
|   MOZ_ASSERT(mRequest);
 | |
| 
 | |
|   RefPtr<nsVariant> variant = new nsVariant();
 | |
|   variant->SetAsVoid();
 | |
| 
 | |
|   mRequest->SetResult(variant);
 | |
| }
 | |
| 
 | |
| void QuotaRequestChild::HandleResponse(bool aResponse) {
 | |
|   AssertIsOnOwningThread();
 | |
|   MOZ_ASSERT(mRequest);
 | |
| 
 | |
|   RefPtr<nsVariant> variant = new nsVariant();
 | |
|   variant->SetAsBool(aResponse);
 | |
| 
 | |
|   mRequest->SetResult(variant);
 | |
| }
 | |
| 
 | |
| void QuotaRequestChild::HandleResponse(const nsAString& aResponse) {
 | |
|   AssertIsOnOwningThread();
 | |
|   MOZ_ASSERT(mRequest);
 | |
| 
 | |
|   RefPtr<nsVariant> variant = new nsVariant();
 | |
|   variant->SetAsAString(aResponse);
 | |
| 
 | |
|   mRequest->SetResult(variant);
 | |
| }
 | |
| 
 | |
| void QuotaRequestChild::HandleResponse(const EstimateResponse& aResponse) {
 | |
|   AssertIsOnOwningThread();
 | |
|   MOZ_ASSERT(mRequest);
 | |
| 
 | |
|   RefPtr<EstimateResult> result =
 | |
|       new EstimateResult(aResponse.usage(), aResponse.limit());
 | |
| 
 | |
|   RefPtr<nsVariant> variant = new nsVariant();
 | |
|   variant->SetAsInterface(NS_GET_IID(nsIQuotaEstimateResult), result);
 | |
| 
 | |
|   mRequest->SetResult(variant);
 | |
| }
 | |
| 
 | |
| void QuotaRequestChild::HandleResponse(const nsTArray<nsCString>& aResponse) {
 | |
|   AssertIsOnOwningThread();
 | |
|   MOZ_ASSERT(mRequest);
 | |
| 
 | |
|   RefPtr<nsVariant> variant = new nsVariant();
 | |
| 
 | |
|   if (aResponse.IsEmpty()) {
 | |
|     variant->SetAsEmptyArray();
 | |
|   } else {
 | |
|     nsTArray<const char*> stringPointers(aResponse.Length());
 | |
|     std::transform(aResponse.cbegin(), aResponse.cend(),
 | |
|                    MakeBackInserter(stringPointers),
 | |
|                    std::mem_fn(&nsCString::get));
 | |
| 
 | |
|     variant->SetAsArray(nsIDataType::VTYPE_CHAR_STR, nullptr,
 | |
|                         stringPointers.Length(), stringPointers.Elements());
 | |
|   }
 | |
| 
 | |
|   mRequest->SetResult(variant);
 | |
| }
 | |
| 
 | |
| void QuotaRequestChild::ActorDestroy(ActorDestroyReason aWhy) {
 | |
|   AssertIsOnOwningThread();
 | |
| }
 | |
| 
 | |
| mozilla::ipc::IPCResult QuotaRequestChild::Recv__delete__(
 | |
|     const RequestResponse& aResponse) {
 | |
|   AssertIsOnOwningThread();
 | |
|   MOZ_ASSERT(mRequest);
 | |
| 
 | |
|   switch (aResponse.type()) {
 | |
|     case RequestResponse::Tnsresult:
 | |
|       HandleResponse(aResponse.get_nsresult());
 | |
|       break;
 | |
| 
 | |
|     case RequestResponse::TStorageNameResponse:
 | |
|       HandleResponse(aResponse.get_StorageNameResponse().name());
 | |
|       break;
 | |
| 
 | |
|     case RequestResponse::TStorageInitializedResponse:
 | |
|       HandleResponse(aResponse.get_StorageInitializedResponse().initialized());
 | |
|       break;
 | |
| 
 | |
|     case RequestResponse::TTemporaryStorageInitializedResponse:
 | |
|       HandleResponse(
 | |
|           aResponse.get_TemporaryStorageInitializedResponse().initialized());
 | |
|       break;
 | |
| 
 | |
|     case RequestResponse::TInitResponse:
 | |
|     case RequestResponse::TInitTemporaryStorageResponse:
 | |
|     case RequestResponse::TClearOriginResponse:
 | |
|     case RequestResponse::TResetOriginResponse:
 | |
|     case RequestResponse::TClearDataResponse:
 | |
|     case RequestResponse::TClearAllResponse:
 | |
|     case RequestResponse::TResetAllResponse:
 | |
|     case RequestResponse::TPersistResponse:
 | |
|       HandleResponse();
 | |
|       break;
 | |
| 
 | |
|     case RequestResponse::TInitializePersistentOriginResponse:
 | |
|       HandleResponse(
 | |
|           aResponse.get_InitializePersistentOriginResponse().created());
 | |
|       break;
 | |
| 
 | |
|     case RequestResponse::TInitializeTemporaryOriginResponse:
 | |
|       HandleResponse(
 | |
|           aResponse.get_InitializeTemporaryOriginResponse().created());
 | |
|       break;
 | |
| 
 | |
|     case RequestResponse::TPersistedResponse:
 | |
|       HandleResponse(aResponse.get_PersistedResponse().persisted());
 | |
|       break;
 | |
| 
 | |
|     case RequestResponse::TEstimateResponse:
 | |
|       HandleResponse(aResponse.get_EstimateResponse());
 | |
|       break;
 | |
| 
 | |
|     case RequestResponse::TListOriginsResponse:
 | |
|       HandleResponse(aResponse.get_ListOriginsResponse().origins());
 | |
|       break;
 | |
| 
 | |
|     default:
 | |
|       MOZ_CRASH("Unknown response type!");
 | |
|   }
 | |
| 
 | |
|   return IPC_OK();
 | |
| }
 | |
| 
 | |
| }  // namespace mozilla::dom::quota
 |