Files
UnrealEngineUWP/Engine/Source/Runtime/Online/BackgroundHTTP/Private/IOS/ApplePlatformBackgroundHttpManager.cpp
dmytro ivanov 1f41b6f103 - Fixing broken reuse of existing downloads
- Added ability to retry stale background downloads when we're in foreground on iOS
- Fixing race condition on background file hash helper invoked from different threads
#rb adam.kinge

[CL 34453579 by dmytro ivanov in ue5-main branch]
2024-06-18 06:18:33 -04:00

105 lines
3.6 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "IOS/ApplePlatformBackgroundHttpManager.h"
#include "IOS/ApplePlatformBackgroundHttp.h"
#include "IOS/ApplePlatformBackgroundHttpRequest.h"
#include "IOS/ApplePlatformBackgroundHttpResponse.h"
#include "HAL/PlatformFileManager.h"
#include "HAL/PlatformAtomics.h"
#include "Misc/ConfigCacheIni.h"
#include "Misc/CoreDelegates.h"
#include "Misc/ScopeRWLock.h"
#include "Stats/Stats.h"
#include "IOS/IOSBackgroundURLSessionHandler.h"
#include "PlatformBackgroundHttp.h"
void FApplePlatformBackgroundHttpManager::AddRequest(const FBackgroundHttpRequestPtr GenericRequest)
{
FAppleBackgroundHttpRequestPtr Request = StaticCastSharedPtr<FApplePlatformBackgroundHttpRequest>(GenericRequest);
if (!ensureAlwaysMsgf(Request.IsValid(), TEXT("Adding a non-Apple background request to our Apple Background Http Manager2! This is not supported or expected!")))
{
return;
}
if (AssociateWithAnyExistingRequest(Request))
{
return;
}
const uint64 DownloadId = FBackgroundURLSessionHandler::CreateOrFindDownload(Request->GetURLList(), Request->GetNSURLSessionPriority(), GetFileHashHelper());
Request->SetInternalDownloadId(DownloadId);
// Should never happen in practice
if (DownloadId == FBackgroundURLSessionHandler::InvalidDownloadId)
{
FBackgroundHttpResponsePtr Response = FPlatformBackgroundHttp::ConstructBackgroundResponse(EHttpResponseCodes::ServerError, FString());
Request->CompleteWithExistingResponseData(Response);
return;
}
{
FRWScopeLock ActiveScopeLock(ActiveRequestLock, SLT_Write);
ActiveRequests.Add(Request);
}
++NumCurrentlyActiveRequests;
}
void FApplePlatformBackgroundHttpManager::RemoveRequest(const FBackgroundHttpRequestPtr GenericRequest)
{
// UpdateProgress might call RemoveRequest, so we could deadlock on ActiveRequestLock if we try to edit ActiveRequests
FRWScopeLock PendingScopeRemoveRequestLock(PendingRemoveRequestLock, SLT_Write);
PendingRemoveRequests.Add(GenericRequest);
}
void FApplePlatformBackgroundHttpManager::SetCellularPreference(int32 Value)
{
FBackgroundURLSessionHandler::AllowCellular(Value > 0);
}
bool FApplePlatformBackgroundHttpManager::Tick(float DeltaTime)
{
QUICK_SCOPE_CYCLE_COUNTER(STAT_FApplePlatformBackgroundHttpManager_Tick);
ensureAlwaysMsgf(IsInGameThread(), TEXT("Called from un-expected thread! Potential error in an implementation of background downloads!"));
{
FRWScopeLock ScopeLock(ActiveRequestLock, SLT_ReadOnly);
for (FBackgroundHttpRequestPtr& GenericRequest : ActiveRequests)
{
FAppleBackgroundHttpRequestPtr Request = StaticCastSharedPtr<FApplePlatformBackgroundHttpRequest>(GenericRequest);
if (ensureAlwaysMsgf(Request.IsValid(), TEXT("Invalid Request Pointer in ActiveRequests list!")))
{
Request->UpdateProgress();
}
}
}
{
FRWScopeLock PendingScopeRemoveRequestLock(PendingRemoveRequestLock, SLT_Write);
for (FBackgroundHttpRequestPtr& GenericRequest : PendingRemoveRequests)
{
FAppleBackgroundHttpRequestPtr Request = StaticCastSharedPtr<FApplePlatformBackgroundHttpRequest>(GenericRequest);
if (ensureAlwaysMsgf(Request.IsValid(), TEXT("Adding a non-Apple background request to our Apple Background Http Manager2! This is not supported or expected!")))
{
const uint64 DownloadId = Request->GetInternalDownloadId();
FBackgroundURLSessionHandler::CancelDownload(DownloadId);
Request->SetInternalDownloadId(FBackgroundURLSessionHandler::InvalidDownloadId);
FBackgroundHttpManagerImpl::RemoveRequest(Request);
}
}
PendingRemoveRequests.Empty();
}
FBackgroundURLSessionHandler::SaveBackgroundHttpFileHashHelperState();
return true;
}