mirror of
https://github.com/stenzek/duckstation.git
synced 2026-02-04 05:04:33 +00:00
HTTPDownloader: Use release-acquire ordering for request state
This commit is contained in:
@@ -98,20 +98,21 @@ void HTTPDownloader::LockedPollRequests(std::unique_lock<std::mutex>& lock)
|
|||||||
for (size_t index = 0; index < m_pending_http_requests.size();)
|
for (size_t index = 0; index < m_pending_http_requests.size();)
|
||||||
{
|
{
|
||||||
Request* req = m_pending_http_requests[index];
|
Request* req = m_pending_http_requests[index];
|
||||||
if (req->state == Request::State::Pending)
|
const Request::State req_state = req->state.load(std::memory_order_acquire);
|
||||||
|
if (req_state == Request::State::Pending)
|
||||||
{
|
{
|
||||||
unstarted_requests++;
|
unstarted_requests++;
|
||||||
index++;
|
index++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((req->state == Request::State::Started || req->state == Request::State::Receiving) &&
|
if ((req_state == Request::State::Started || req_state == Request::State::Receiving) &&
|
||||||
current_time >= req->start_time && Timer::ConvertValueToSeconds(current_time - req->start_time) >= m_timeout)
|
current_time >= req->start_time && Timer::ConvertValueToSeconds(current_time - req->start_time) >= m_timeout)
|
||||||
{
|
{
|
||||||
// request timed out
|
// request timed out
|
||||||
ERROR_LOG("Request for '{}' timed out", req->url);
|
ERROR_LOG("Request for '{}' timed out", req->url);
|
||||||
|
|
||||||
req->state.store(Request::State::Cancelled);
|
req->state.store(Request::State::Cancelled, std::memory_order_release);
|
||||||
m_pending_http_requests.erase(m_pending_http_requests.begin() + index);
|
m_pending_http_requests.erase(m_pending_http_requests.begin() + index);
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
|
|
||||||
@@ -123,13 +124,13 @@ void HTTPDownloader::LockedPollRequests(std::unique_lock<std::mutex>& lock)
|
|||||||
lock.lock();
|
lock.lock();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if ((req->state == Request::State::Started || req->state == Request::State::Receiving) && req->progress &&
|
else if ((req_state == Request::State::Started || req_state == Request::State::Receiving) && req->progress &&
|
||||||
req->progress->IsCancelled())
|
req->progress->IsCancelled())
|
||||||
{
|
{
|
||||||
// request timed out
|
// request timed out
|
||||||
ERROR_LOG("Request for '{}' cancelled", req->url);
|
ERROR_LOG("Request for '{}' cancelled", req->url);
|
||||||
|
|
||||||
req->state.store(Request::State::Cancelled);
|
req->state.store(Request::State::Cancelled, std::memory_order_release);
|
||||||
m_pending_http_requests.erase(m_pending_http_requests.begin() + index);
|
m_pending_http_requests.erase(m_pending_http_requests.begin() + index);
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
|
|
||||||
@@ -142,7 +143,7 @@ void HTTPDownloader::LockedPollRequests(std::unique_lock<std::mutex>& lock)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req->state != Request::State::Complete)
|
if (req_state != Request::State::Complete)
|
||||||
{
|
{
|
||||||
if (req->progress)
|
if (req->progress)
|
||||||
{
|
{
|
||||||
@@ -245,9 +246,10 @@ void HTTPDownloader::LockedAddRequest(Request* request)
|
|||||||
u32 HTTPDownloader::LockedGetActiveRequestCount()
|
u32 HTTPDownloader::LockedGetActiveRequestCount()
|
||||||
{
|
{
|
||||||
u32 count = 0;
|
u32 count = 0;
|
||||||
for (Request* req : m_pending_http_requests)
|
for (const Request* const req : m_pending_http_requests)
|
||||||
{
|
{
|
||||||
if (req->state == Request::State::Started || req->state == Request::State::Receiving)
|
const Request::State req_state = req->state.load(std::memory_order_acquire);
|
||||||
|
if (req_state == Request::State::Started || req_state == Request::State::Receiving)
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ void CALLBACK HTTPDownloaderWinHttp::HTTPStatusCallback(HINTERNET hRequest, DWOR
|
|||||||
ERROR_LOG("WinHttp async function {} returned error {}", res->dwResult, res->dwError);
|
ERROR_LOG("WinHttp async function {} returned error {}", res->dwResult, res->dwError);
|
||||||
req->status_code = HTTP_STATUS_ERROR;
|
req->status_code = HTTP_STATUS_ERROR;
|
||||||
req->error.SetStringFmt("WinHttp async function {} returned error {}", res->dwResult, res->dwError);
|
req->error.SetStringFmt("WinHttp async function {} returned error {}", res->dwResult, res->dwError);
|
||||||
req->state.store(Request::State::Complete);
|
req->state.store(Request::State::Complete, std::memory_order_release);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE:
|
case WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE:
|
||||||
@@ -139,7 +139,7 @@ void CALLBACK HTTPDownloaderWinHttp::HTTPStatusCallback(HINTERNET hRequest, DWOR
|
|||||||
ERROR_LOG("WinHttpReceiveResponse() failed: {}", err);
|
ERROR_LOG("WinHttpReceiveResponse() failed: {}", err);
|
||||||
req->status_code = HTTP_STATUS_ERROR;
|
req->status_code = HTTP_STATUS_ERROR;
|
||||||
req->error.SetWin32("WinHttpReceiveResponse() failed: ", err);
|
req->error.SetWin32("WinHttpReceiveResponse() failed: ", err);
|
||||||
req->state.store(Request::State::Complete);
|
req->state.store(Request::State::Complete, std::memory_order_release);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -156,7 +156,7 @@ void CALLBACK HTTPDownloaderWinHttp::HTTPStatusCallback(HINTERNET hRequest, DWOR
|
|||||||
ERROR_LOG("WinHttpQueryHeaders() for status code failed: {}", err);
|
ERROR_LOG("WinHttpQueryHeaders() for status code failed: {}", err);
|
||||||
req->status_code = HTTP_STATUS_ERROR;
|
req->status_code = HTTP_STATUS_ERROR;
|
||||||
req->error.SetWin32("WinHttpQueryHeaders() failed: ", err);
|
req->error.SetWin32("WinHttpQueryHeaders() failed: ", err);
|
||||||
req->state.store(Request::State::Complete);
|
req->state.store(Request::State::Complete, std::memory_order_release);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,7 +188,7 @@ void CALLBACK HTTPDownloaderWinHttp::HTTPStatusCallback(HINTERNET hRequest, DWOR
|
|||||||
|
|
||||||
DEV_LOG("Status code {}, content-length is {}", req->status_code, req->content_length);
|
DEV_LOG("Status code {}, content-length is {}", req->status_code, req->content_length);
|
||||||
req->data.reserve(req->content_length);
|
req->data.reserve(req->content_length);
|
||||||
req->state = Request::State::Receiving;
|
req->state.store(Request::State::Receiving, std::memory_order_release);
|
||||||
|
|
||||||
// start reading
|
// start reading
|
||||||
if (!WinHttpQueryDataAvailable(hRequest, nullptr) && GetLastError() != ERROR_IO_PENDING)
|
if (!WinHttpQueryDataAvailable(hRequest, nullptr) && GetLastError() != ERROR_IO_PENDING)
|
||||||
@@ -197,7 +197,7 @@ void CALLBACK HTTPDownloaderWinHttp::HTTPStatusCallback(HINTERNET hRequest, DWOR
|
|||||||
ERROR_LOG("WinHttpQueryDataAvailable() failed: {}", err);
|
ERROR_LOG("WinHttpQueryDataAvailable() failed: {}", err);
|
||||||
req->status_code = HTTP_STATUS_ERROR;
|
req->status_code = HTTP_STATUS_ERROR;
|
||||||
req->error.SetWin32("WinHttpQueryDataAvailable() failed: ", err);
|
req->error.SetWin32("WinHttpQueryDataAvailable() failed: ", err);
|
||||||
req->state.store(Request::State::Complete);
|
req->state.store(Request::State::Complete, std::memory_order_release);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -210,7 +210,7 @@ void CALLBACK HTTPDownloaderWinHttp::HTTPStatusCallback(HINTERNET hRequest, DWOR
|
|||||||
{
|
{
|
||||||
// end of request
|
// end of request
|
||||||
DEV_LOG("End of request '{}', {} bytes received", req->url, req->data.size());
|
DEV_LOG("End of request '{}', {} bytes received", req->url, req->data.size());
|
||||||
req->state.store(Request::State::Complete);
|
req->state.store(Request::State::Complete, std::memory_order_release);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,7 +225,7 @@ void CALLBACK HTTPDownloaderWinHttp::HTTPStatusCallback(HINTERNET hRequest, DWOR
|
|||||||
ERROR_LOG("WinHttpReadData() failed: {}", err);
|
ERROR_LOG("WinHttpReadData() failed: {}", err);
|
||||||
req->status_code = HTTP_STATUS_ERROR;
|
req->status_code = HTTP_STATUS_ERROR;
|
||||||
req->error.SetWin32("WinHttpReadData() failed: ", err);
|
req->error.SetWin32("WinHttpReadData() failed: ", err);
|
||||||
req->state.store(Request::State::Complete);
|
req->state.store(Request::State::Complete, std::memory_order_release);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -245,7 +245,7 @@ void CALLBACK HTTPDownloaderWinHttp::HTTPStatusCallback(HINTERNET hRequest, DWOR
|
|||||||
ERROR_LOG("WinHttpQueryDataAvailable() failed: {}", err);
|
ERROR_LOG("WinHttpQueryDataAvailable() failed: {}", err);
|
||||||
req->status_code = HTTP_STATUS_ERROR;
|
req->status_code = HTTP_STATUS_ERROR;
|
||||||
req->error.SetWin32("WinHttpQueryDataAvailable() failed: ", err);
|
req->error.SetWin32("WinHttpQueryDataAvailable() failed: ", err);
|
||||||
req->state.store(Request::State::Complete);
|
req->state.store(Request::State::Complete, std::memory_order_release);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|||||||
Reference in New Issue
Block a user