From ad8349b7e9f3a2e5ac9c8d48a940b2675b8a84e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20M=C3=BCller?= Date: Sat, 12 Oct 2024 10:28:00 +0200 Subject: [PATCH] Avoid busy waiting in `CHttpRequest::Wait` function Use a condition variable instead of busy waiting until HTTP requests are done. Also set the state `EHttpState::RUNNING` which was previously unused. Closes #7811. --- src/engine/shared/http.cpp | 17 ++++++----------- src/engine/shared/http.h | 2 ++ 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/engine/shared/http.cpp b/src/engine/shared/http.cpp index c69da07dcda..d308abab80b 100644 --- a/src/engine/shared/http.cpp +++ b/src/engine/shared/http.cpp @@ -379,6 +379,7 @@ void CHttpRequest::OnCompletionInternal(void *pHandle, unsigned int Result) // before the result has been initialized/updated in OnCompletion. OnCompletion(State); m_State = State; + m_WaitCondition.notify_all(); } void CHttpRequest::WriteToFile(IStorage *pStorage, const char *pDest, int StorageType) @@ -402,18 +403,11 @@ void CHttpRequest::Header(const char *pNameColonValue) void CHttpRequest::Wait() { - using namespace std::chrono_literals; - - // This is so uncommon that polling just might work - for(;;) - { + std::unique_lock Lock(m_WaitMutex); + m_WaitCondition.wait(Lock, [this]() { EHttpState State = m_State.load(std::memory_order_seq_cst); - if(State != EHttpState::QUEUED && State != EHttpState::RUNNING) - { - return; - } - std::this_thread::sleep_for(10ms); - } + return State != EHttpState::QUEUED && State != EHttpState::RUNNING; + }); } void CHttpRequest::Result(unsigned char **ppResult, size_t *pResultLength) const @@ -604,6 +598,7 @@ void CHttp::RunLoop() goto error_configure; } + pRequest->m_State = EHttpState::RUNNING; m_RunningRequests.emplace(pEH, std::move(pRequest)); NewRequests.pop_front(); continue; diff --git a/src/engine/shared/http.h b/src/engine/shared/http.h index 86e53fac9fd..40bef7771fc 100644 --- a/src/engine/shared/http.h +++ b/src/engine/shared/http.h @@ -116,6 +116,8 @@ class CHttpRequest : public IHttpRequest char m_aErr[256]; // 256 == CURL_ERROR_SIZE std::atomic m_State{EHttpState::QUEUED}; std::atomic m_Abort{false}; + std::mutex m_WaitMutex; + std::condition_variable m_WaitCondition; int m_StatusCode = 0; bool m_HeadersEnded = false;