// note that we cannot call parent implementation because lock might be possible non-multiple void FCurlHttpManager::AddRequest(TSharedRef<class IHttpRequest> Request) { FScopeLock ScopeLock(&RequestLock); Requests.AddUnique(Request); FCurlHttpRequest* CurlRequest = static_cast< FCurlHttpRequest* >( &Request.Get() ); HandlesToRequests.Add(CurlRequest->GetEasyHandle(), Request); }
// note that we cannot call parent implementation because lock might be possible non-multiple void FCurlHttpManager::RemoveRequest(const TSharedRef<class IHttpRequest>& Request) { FScopeLock ScopeLock(&RequestLock); // Keep track of requests that have been removed to be destroyed later PendingDestroyRequests.AddUnique(FRequestPendingDestroy(DeferredDestroyDelay,Request)); FCurlHttpRequest* CurlRequest = static_cast< FCurlHttpRequest* >( &Request.Get() ); HandlesToRequests.Remove(CurlRequest->GetEasyHandle()); Requests.Remove(Request); }
bool FCurlHttpManager::Tick(float DeltaSeconds) { check(MultiHandle); if (Requests.Num() > 0) { FScopeLock ScopeLock(&RequestLock); int RunningRequests = -1; curl_multi_perform(MultiHandle, &RunningRequests); // read more info if number of requests changed or if there's zero running // (note that some requests might have never be "running" from libcurl's point of view) if (RunningRequests == 0 || RunningRequests != LastRunningRequests) { for(;;) { int MsgsStillInQueue = 0; // may use that to impose some upper limit we may spend in that loop CURLMsg * Message = curl_multi_info_read(MultiHandle, &MsgsStillInQueue); if (Message == NULL) { break; } // find out which requests have completed if (Message->msg == CURLMSG_DONE) { CURL* CompletedHandle = Message->easy_handle; TSharedRef<IHttpRequest> * RequestRefPtr = HandlesToRequests.Find(CompletedHandle); if (RequestRefPtr) { FCurlHttpRequest* CurlRequest = static_cast< FCurlHttpRequest* >( &RequestRefPtr->Get() ); CurlRequest->MarkAsCompleted(Message->data.result); UE_LOG(LogHttp, Verbose, TEXT("Request %p (easy handle:%p) has completed (code:%d) and has been marked as such"), CurlRequest, CompletedHandle, (int32)Message->data.result); } else { UE_LOG(LogHttp, Warning, TEXT("Could not find mapping for completed request (easy handle: %p)"), CompletedHandle); } } } } LastRunningRequests = RunningRequests; } // we should be outside scope lock here to be able to call parent! return FHttpManager::Tick(DeltaSeconds); }