Changeset - r28347:0fa07887e1b3
[Not reviewed]
master
0 1 0
Patric Stout - 11 months ago 2023-12-29 11:45:23
truebrain@openttd.org
Fix: race-condition when creating new HTTP requests from different threads (#11638)
1 file changed with 11 insertions and 4 deletions:
0 comments (0 inline, 0 general)
src/network/core/http_winhttp.cpp
Show inline comments
 
@@ -13,12 +13,13 @@
 
#include "../../debug.h"
 
#include "../../rev.h"
 
#include "../network_internal.h"
 

	
 
#include "http.h"
 

	
 
#include <mutex>
 
#include <winhttp.h>
 

	
 
#include "../../safeguards.h"
 

	
 
static HINTERNET _winhttp_session = nullptr;
 

	
 
@@ -43,12 +44,13 @@ public:
 
	bool Receive();
 
	void WinHttpCallback(DWORD code, void *info, DWORD length);
 
};
 

	
 
static std::vector<NetworkHTTPRequest *> _http_requests;
 
static std::vector<NetworkHTTPRequest *> _new_http_requests;
 
static std::mutex _new_http_requests_mutex;
 

	
 
/**
 
 * Create a new HTTP request.
 
 *
 
 * @param uri      the URI to connect to (https://.../..).
 
 * @param callback the callback to send data back on.
 
@@ -280,21 +282,26 @@ NetworkHTTPRequest::~NetworkHTTPRequest(
 
}
 

	
 
/* static */ void NetworkHTTPSocketHandler::Connect(const std::string &uri, HTTPCallback *callback, const std::string data)
 
{
 
	auto request = new NetworkHTTPRequest(std::wstring(uri.begin(), uri.end()), callback, data);
 
	request->Connect();
 

	
 
	std::lock_guard<std::mutex> lock(_new_http_requests_mutex);
 
	_new_http_requests.push_back(request);
 
}
 

	
 
/* static */ void NetworkHTTPSocketHandler::HTTPReceive()
 
{
 
	if (!_new_http_requests.empty()) {
 
		/* We delay adding new requests, as Receive() below can cause a callback which adds a new requests. */
 
		_http_requests.insert(_http_requests.end(), _new_http_requests.begin(), _new_http_requests.end());
 
		_new_http_requests.clear();
 
	{
 
		std::lock_guard<std::mutex> lock(_new_http_requests_mutex);
 
		if (!_new_http_requests.empty()) {
 
			/* We delay adding new requests, as Receive() below can cause a callback which adds a new requests. */
 
			_http_requests.insert(_http_requests.end(), _new_http_requests.begin(), _new_http_requests.end());
 
			_new_http_requests.clear();
 
		}
 
	}
 

	
 
	if (_http_requests.empty()) return;
 

	
 
	for (auto it = _http_requests.begin(); it != _http_requests.end(); /* nothing */) {
 
		NetworkHTTPRequest *cur = *it;
0 comments (0 inline, 0 general)