Merge branch 'master' into jgrpp

# Conflicts:
#	src/company_cmd.cpp
#	src/company_func.h
#	src/core/overflowsafe_type.hpp
#	src/engine.cpp
#	src/music/midifile.cpp
#	src/network/network_command.cpp
#	src/newgrf_debug_gui.cpp
#	src/newgrf_roadstop.h
#	src/newgrf_spritegroup.cpp
#	src/os/macosx/crashlog_osx.cpp
#	src/os/unix/crashlog_unix.cpp
#	src/pathfinder/yapf/yapf_common.hpp
#	src/road_gui.cpp
#	src/saveload/engine_sl.cpp
#	src/script/api/script_depotlist.cpp
#	src/script/api/script_roadtypelist.cpp
#	src/settings_gui.cpp
#	src/settings_type.h
#	src/strings.cpp
#	src/table/settings/game_settings.ini
This commit is contained in:
Jonathan G Rennison
2024-01-05 13:37:52 +00:00
136 changed files with 1198 additions and 1032 deletions

View File

@@ -57,7 +57,7 @@ static void NetworkFindBroadcastIPsInternal(NetworkAddressList *broadcast) // Wi
memcpy(&address, &ifo[j].iiAddress.Address, sizeof(sockaddr));
((sockaddr_in*)&address)->sin_addr.s_addr = ifo[j].iiAddress.AddressIn.sin_addr.s_addr | ~ifo[j].iiNetmask.AddressIn.sin_addr.s_addr;
NetworkAddress addr(address, sizeof(sockaddr));
if (std::none_of(broadcast->begin(), broadcast->end(), [&addr](NetworkAddress const& elem) -> bool { return elem == addr; })) broadcast->push_back(addr);
if (std::none_of(broadcast->begin(), broadcast->end(), [&addr](NetworkAddress const &elem) -> bool { return elem == addr; })) broadcast->push_back(addr);
}
free(ifo);
@@ -77,7 +77,7 @@ static void NetworkFindBroadcastIPsInternal(NetworkAddressList *broadcast)
if (ifa->ifa_broadaddr->sa_family != AF_INET) continue;
NetworkAddress addr(ifa->ifa_broadaddr, sizeof(sockaddr));
if (std::none_of(broadcast->begin(), broadcast->end(), [&addr](NetworkAddress const& elem) -> bool { return elem == addr; })) broadcast->push_back(addr);
if (std::none_of(broadcast->begin(), broadcast->end(), [&addr](NetworkAddress const &elem) -> bool { return elem == addr; })) broadcast->push_back(addr);
}
freeifaddrs(ifap);
}

View File

@@ -233,8 +233,10 @@ void HttpThread()
request->callback.OnFailure();
}
/* Wait till the callback tells us all data is dequeued. */
request->callback.WaitTillEmpty();
/* Wait till the callback tells us all data is dequeued, or _http_thread_exit has been set. */
request->callback.WaitTillEmptyOrCondition([]() -> bool {
return _http_thread_exit;
});
}
curl_easy_cleanup(curl);
@@ -277,10 +279,13 @@ void NetworkHTTPInitialize()
void NetworkHTTPUninitialize()
{
curl_global_cleanup();
_http_thread_exit = true;
/* Queues must be cleared (and the queue CV signalled) after _http_thread_exit is set to ensure that the HTTP thread can exit */
for (auto &callback : _http_callbacks) {
callback->ClearQueue();
}
{
std::lock_guard<std::mutex> lock(_http_mutex);
_http_cv.notify_one();
@@ -289,4 +294,6 @@ void NetworkHTTPUninitialize()
if (_http_thread.joinable()) {
_http_thread.join();
}
curl_global_cleanup();
}

View File

@@ -74,13 +74,15 @@ public:
}
/**
* Wait till the queue is dequeued.
* Wait till the queue is dequeued, or a condition is met.
* @param condition Condition functor.
*/
void WaitTillEmpty()
template <typename T>
void WaitTillEmptyOrCondition(T condition)
{
std::unique_lock<std::mutex> lock(this->mutex);
while (!queue.empty()) {
while (!(queue.empty() || condition())) {
this->queue_cv.wait(lock);
}
}
@@ -94,6 +96,20 @@ public:
return this->queue.empty();
}
/**
* Clear everything in the queue.
*
* Should be called from the Game Thread.
*/
void ClearQueue()
{
std::lock_guard<std::mutex> lock(this->mutex);
this->queue.clear();
this->queue_cv.notify_all();
}
HTTPThreadSafeCallback(HTTPCallback *callback) : callback(callback) {}
~HTTPThreadSafeCallback()