Merge branches 'crashlog_improvements', 'save_ext' into jgrpp
# Conflicts: # Makefile.src.in # projects/openttd_vs140.vcxproj # projects/openttd_vs140.vcxproj.filters # projects/openttd_vs141.vcxproj # projects/openttd_vs141.vcxproj.filters # projects/openttd_vs142.vcxproj # projects/openttd_vs142.vcxproj.filters # src/core/smallstack_type.hpp # src/linkgraph/linkgraphjob.cpp # src/linkgraph/linkgraphjob.h # src/misc.cpp # src/network/network_udp.cpp # src/openttd.cpp # src/saveload/saveload.cpp
This commit is contained in:
@@ -63,7 +63,6 @@ public:
|
||||
*/
|
||||
class TCPConnecter {
|
||||
private:
|
||||
class ThreadObject *thread; ///< Thread used to create the TCP connection
|
||||
bool connected; ///< Whether we succeeded in making the connection
|
||||
bool aborted; ///< Whether we bailed out (i.e. connection making failed)
|
||||
bool killed; ///< Whether we got killed
|
||||
@@ -71,7 +70,7 @@ private:
|
||||
|
||||
void Connect();
|
||||
|
||||
static void ThreadEntry(void *param);
|
||||
static void ThreadEntry(TCPConnecter *param);
|
||||
|
||||
protected:
|
||||
/** Address we're connecting to */
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
*/
|
||||
|
||||
#include "../../stdafx.h"
|
||||
#include "../../thread/thread.h"
|
||||
#include "../../thread.h"
|
||||
|
||||
#include "tcp.h"
|
||||
|
||||
@@ -33,7 +33,7 @@ TCPConnecter::TCPConnecter(const NetworkAddress &address) :
|
||||
address(address)
|
||||
{
|
||||
_tcp_connecters.push_back(this);
|
||||
if (!ThreadObject::New(TCPConnecter::ThreadEntry, this, &this->thread, "ottd:tcp")) {
|
||||
if (!StartNewThread(NULL, "ottd:tcp", &TCPConnecter::ThreadEntry, this)) {
|
||||
this->Connect();
|
||||
}
|
||||
}
|
||||
@@ -53,9 +53,9 @@ void TCPConnecter::Connect()
|
||||
* Entry point for the new threads.
|
||||
* @param param the TCPConnecter instance to call Connect on.
|
||||
*/
|
||||
/* static */ void TCPConnecter::ThreadEntry(void *param)
|
||||
/* static */ void TCPConnecter::ThreadEntry(TCPConnecter *param)
|
||||
{
|
||||
static_cast<TCPConnecter*>(param)->Connect();
|
||||
param->Connect();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "network_base.h"
|
||||
#include "network_client.h"
|
||||
#include "../core/backup_type.hpp"
|
||||
#include "../thread.h"
|
||||
|
||||
#include "table/strings.h"
|
||||
|
||||
|
||||
@@ -15,19 +15,17 @@
|
||||
#include "../stdafx.h"
|
||||
#include "../debug.h"
|
||||
#include "../window_func.h"
|
||||
#include "../thread/thread.h"
|
||||
#include "network_internal.h"
|
||||
#include "network_udp.h"
|
||||
#include "network_gamelist.h"
|
||||
#include <atomic>
|
||||
|
||||
#include "../safeguards.h"
|
||||
|
||||
NetworkGameList *_network_game_list = NULL;
|
||||
|
||||
/** Mutex for handling delayed insertion/querying of servers. */
|
||||
static ThreadMutex *_network_game_list_mutex = ThreadMutex::New();
|
||||
/** The games to insert when the GUI thread has time for us. */
|
||||
static NetworkGameList *_network_game_delayed_insertion_list = NULL;
|
||||
static std::atomic<NetworkGameList *> _network_game_delayed_insertion_list(NULL);
|
||||
|
||||
/**
|
||||
* Add a new item to the linked gamelist, but do it delayed in the next tick
|
||||
@@ -36,19 +34,17 @@ static NetworkGameList *_network_game_delayed_insertion_list = NULL;
|
||||
*/
|
||||
void NetworkGameListAddItemDelayed(NetworkGameList *item)
|
||||
{
|
||||
_network_game_list_mutex->BeginCritical();
|
||||
item->next = _network_game_delayed_insertion_list;
|
||||
_network_game_delayed_insertion_list = item;
|
||||
_network_game_list_mutex->EndCritical();
|
||||
item->next = _network_game_delayed_insertion_list.load(std::memory_order_relaxed);
|
||||
while (!_network_game_delayed_insertion_list.compare_exchange_weak(item->next, item, std::memory_order_acq_rel)) {}
|
||||
}
|
||||
|
||||
/** Perform the delayed (thread safe) insertion into the game list */
|
||||
static void NetworkGameListHandleDelayedInsert()
|
||||
{
|
||||
_network_game_list_mutex->BeginCritical();
|
||||
while (_network_game_delayed_insertion_list != NULL) {
|
||||
NetworkGameList *ins_item = _network_game_delayed_insertion_list;
|
||||
_network_game_delayed_insertion_list = ins_item->next;
|
||||
while (true) {
|
||||
NetworkGameList *ins_item = _network_game_delayed_insertion_list.load(std::memory_order_relaxed);
|
||||
while (ins_item != NULL && !_network_game_delayed_insertion_list.compare_exchange_weak(ins_item, ins_item->next, std::memory_order_acq_rel)) {}
|
||||
if (ins_item == NULL) break; // No item left.
|
||||
|
||||
NetworkGameList *item = NetworkGameListAddItem(ins_item->address);
|
||||
|
||||
@@ -66,7 +62,6 @@ static void NetworkGameListHandleDelayedInsert()
|
||||
}
|
||||
free(ins_item);
|
||||
}
|
||||
_network_game_list_mutex->EndCritical();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
#include "../core/pool_func.hpp"
|
||||
#include "../core/random_func.hpp"
|
||||
#include "../rev.h"
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
|
||||
#include "../safeguards.h"
|
||||
|
||||
@@ -58,7 +60,8 @@ struct PacketWriter : SaveFilter {
|
||||
Packet *current; ///< The packet we're currently writing to.
|
||||
size_t total_size; ///< Total size of the compressed savegame.
|
||||
Packet *packets; ///< Packet queue of the savegame; send these "slowly" to the client.
|
||||
ThreadMutex *mutex; ///< Mutex for making threaded saving safe.
|
||||
std::mutex mutex; ///< Mutex for making threaded saving safe.
|
||||
std::condition_variable exit_sig; ///< Signal for threaded destruction of this packet writer.
|
||||
|
||||
/**
|
||||
* Create the packet writer.
|
||||
@@ -66,17 +69,14 @@ struct PacketWriter : SaveFilter {
|
||||
*/
|
||||
PacketWriter(ServerNetworkGameSocketHandler *cs) : SaveFilter(NULL), cs(cs), current(NULL), total_size(0), packets(NULL)
|
||||
{
|
||||
this->mutex = ThreadMutex::New();
|
||||
}
|
||||
|
||||
/** Make sure everything is cleaned up. */
|
||||
~PacketWriter()
|
||||
{
|
||||
if (this->mutex != NULL) this->mutex->BeginCritical();
|
||||
std::unique_lock<std::mutex> lock(this->mutex);
|
||||
|
||||
if (this->cs != NULL && this->mutex != NULL) {
|
||||
this->mutex->WaitForSignal();
|
||||
}
|
||||
if (this->cs != NULL) this->exit_sig.wait(lock);
|
||||
|
||||
/* This must all wait until the Destroy function is called. */
|
||||
|
||||
@@ -87,11 +87,6 @@ struct PacketWriter : SaveFilter {
|
||||
}
|
||||
|
||||
delete this->current;
|
||||
|
||||
if (this->mutex != NULL) this->mutex->EndCritical();
|
||||
|
||||
delete this->mutex;
|
||||
this->mutex = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -106,13 +101,12 @@ struct PacketWriter : SaveFilter {
|
||||
*/
|
||||
void Destroy()
|
||||
{
|
||||
if (this->mutex != NULL) this->mutex->BeginCritical();
|
||||
std::unique_lock<std::mutex> lock(this->mutex);
|
||||
|
||||
this->cs = NULL;
|
||||
|
||||
if (this->mutex != NULL) this->mutex->SendSignal();
|
||||
|
||||
if (this->mutex != NULL) this->mutex->EndCritical();
|
||||
this->exit_sig.notify_all();
|
||||
lock.unlock();
|
||||
|
||||
/* Make sure the saving is completely cancelled. Yes,
|
||||
* we need to handle the save finish as well as the
|
||||
@@ -138,14 +132,12 @@ struct PacketWriter : SaveFilter {
|
||||
*/
|
||||
Packet *PopPacket()
|
||||
{
|
||||
if (this->mutex != NULL) this->mutex->BeginCritical();
|
||||
std::lock_guard<std::mutex> lock(this->mutex);
|
||||
|
||||
Packet *p = this->packets;
|
||||
this->packets = p->next;
|
||||
p->next = NULL;
|
||||
|
||||
if (this->mutex != NULL) this->mutex->EndCritical();
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
@@ -170,7 +162,7 @@ struct PacketWriter : SaveFilter {
|
||||
|
||||
if (this->current == NULL) this->current = new Packet(PACKET_SERVER_MAP_DATA);
|
||||
|
||||
if (this->mutex != NULL) this->mutex->BeginCritical();
|
||||
std::lock_guard<std::mutex> lock(this->mutex);
|
||||
|
||||
byte *bufe = buf + size;
|
||||
while (buf != bufe) {
|
||||
@@ -185,8 +177,6 @@ struct PacketWriter : SaveFilter {
|
||||
}
|
||||
}
|
||||
|
||||
if (this->mutex != NULL) this->mutex->EndCritical();
|
||||
|
||||
this->total_size += size;
|
||||
}
|
||||
|
||||
@@ -195,7 +185,7 @@ struct PacketWriter : SaveFilter {
|
||||
/* We want to abort the saving when the socket is closed. */
|
||||
if (this->cs == NULL) SlError(STR_NETWORK_ERROR_LOSTCONNECTION);
|
||||
|
||||
if (this->mutex != NULL) this->mutex->BeginCritical();
|
||||
std::lock_guard<std::mutex> lock(this->mutex);
|
||||
|
||||
/* Make sure the last packet is flushed. */
|
||||
this->AppendQueue();
|
||||
@@ -208,8 +198,6 @@ struct PacketWriter : SaveFilter {
|
||||
Packet *p = new Packet(PACKET_SERVER_MAP_SIZE);
|
||||
p->Send_uint32((uint32)this->total_size);
|
||||
this->cs->NetworkTCPSocketHandler::SendPacket(p);
|
||||
|
||||
if (this->mutex != NULL) this->mutex->EndCritical();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1681,7 +1669,7 @@ static void NetworkAutoCleanCompanies()
|
||||
/* Is the company empty for autoclean_unprotected-months, and is there no protection? */
|
||||
if (_settings_client.network.autoclean_unprotected != 0 && _network_company_states[c->index].months_empty > _settings_client.network.autoclean_unprotected && StrEmpty(_network_company_states[c->index].password)) {
|
||||
/* Shut the company down */
|
||||
DoCommandP(0, CCA_DELETE | c->index << 16, CRR_AUTOCLEAN, CMD_COMPANY_CTRL);
|
||||
DoCommandP(0, CCA_DELETE | c->index << 16 | CRR_AUTOCLEAN << 24, 0, CMD_COMPANY_CTRL);
|
||||
IConsolePrintF(CC_DEFAULT, "Auto-cleaned company #%d with no password", c->index + 1);
|
||||
}
|
||||
/* Is the company empty for autoclean_protected-months, and there is a protection? */
|
||||
@@ -1695,7 +1683,7 @@ static void NetworkAutoCleanCompanies()
|
||||
/* Is the company empty for autoclean_novehicles-months, and has no vehicles? */
|
||||
if (_settings_client.network.autoclean_novehicles != 0 && _network_company_states[c->index].months_empty > _settings_client.network.autoclean_novehicles && vehicles_in_company[c->index] == 0) {
|
||||
/* Shut the company down */
|
||||
DoCommandP(0, CCA_DELETE | c->index << 16, CRR_AUTOCLEAN, CMD_COMPANY_CTRL);
|
||||
DoCommandP(0, CCA_DELETE | c->index << 16 | CRR_AUTOCLEAN << 24, 0, CMD_COMPANY_CTRL);
|
||||
IConsolePrintF(CC_DEFAULT, "Auto-cleaned company #%d with no vehicles", c->index + 1);
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
|
||||
#include "network_internal.h"
|
||||
#include "core/tcp_listen.h"
|
||||
#include "../thread/thread.h"
|
||||
|
||||
class ServerNetworkGameSocketHandler;
|
||||
/** Make the code look slightly nicer/simpler. */
|
||||
|
||||
@@ -24,11 +24,12 @@
|
||||
#include "network.h"
|
||||
#include "../core/endian_func.hpp"
|
||||
#include "../company_base.h"
|
||||
#include "../thread/thread.h"
|
||||
#include "../thread.h"
|
||||
#include "../rev.h"
|
||||
#include "../newgrf_text.h"
|
||||
#include "../strings_func.h"
|
||||
#include "table/strings.h"
|
||||
#include <mutex>
|
||||
|
||||
#include "core/udp.h"
|
||||
|
||||
@@ -40,7 +41,7 @@ extern const uint8 _out_of_band_grf_md5[16] { 0x00, 0xB0, 0xC0, 0xDE, 0x00, 0x00
|
||||
static const uint32 FIND_SERVER_EXTENDED_TOKEN = 0x2A49582A;
|
||||
|
||||
/** Mutex for all out threaded udp resolution and such. */
|
||||
static ThreadMutex *_network_udp_mutex = ThreadMutex::New();
|
||||
static std::mutex _network_udp_mutex;
|
||||
|
||||
/** Session key to register ourselves to the master server */
|
||||
static uint64 _session_key = 0;
|
||||
@@ -53,22 +54,6 @@ NetworkUDPSocketHandler *_udp_client_socket = NULL; ///< udp client socket
|
||||
NetworkUDPSocketHandler *_udp_server_socket = NULL; ///< udp server socket
|
||||
NetworkUDPSocketHandler *_udp_master_socket = NULL; ///< udp master socket
|
||||
|
||||
/** Simpler wrapper struct for NetworkUDPQueryServerThread */
|
||||
struct NetworkUDPQueryServerInfo : NetworkAddress {
|
||||
bool manually; ///< Did we connect manually or not?
|
||||
|
||||
/**
|
||||
* Create the structure.
|
||||
* @param address The address of the server to query.
|
||||
* @param manually Whether the address was entered manually.
|
||||
*/
|
||||
NetworkUDPQueryServerInfo(const NetworkAddress &address, bool manually) :
|
||||
NetworkAddress(address),
|
||||
manually(manually)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
static Packet PrepareUdpClientFindServerPacket()
|
||||
{
|
||||
Packet p(PACKET_UDP_CLIENT_FIND_SERVER);
|
||||
@@ -84,33 +69,21 @@ static Packet PrepareUdpClientFindServerPacket()
|
||||
* @param needs_mutex Whether we need to acquire locks when sending the packet or not.
|
||||
* @param manually Whether the address was entered manually.
|
||||
*/
|
||||
static void NetworkUDPQueryServer(NetworkAddress *address, bool needs_mutex, bool manually)
|
||||
static void DoNetworkUDPQueryServer(NetworkAddress &address, bool needs_mutex, bool manually)
|
||||
{
|
||||
/* Clear item in gamelist */
|
||||
NetworkGameList *item = CallocT<NetworkGameList>(1);
|
||||
address->GetAddressAsString(item->info.server_name, lastof(item->info.server_name));
|
||||
strecpy(item->info.hostname, address->GetHostname(), lastof(item->info.hostname));
|
||||
item->address = *address;
|
||||
address.GetAddressAsString(item->info.server_name, lastof(item->info.server_name));
|
||||
strecpy(item->info.hostname, address.GetHostname(), lastof(item->info.hostname));
|
||||
item->address = address;
|
||||
item->manually = manually;
|
||||
NetworkGameListAddItemDelayed(item);
|
||||
|
||||
if (needs_mutex) _network_udp_mutex->BeginCritical();
|
||||
std::unique_lock<std::mutex> lock(_network_udp_mutex, std::defer_lock);
|
||||
if (needs_mutex) lock.lock();
|
||||
/* Init the packet */
|
||||
Packet p = PrepareUdpClientFindServerPacket();
|
||||
if (_udp_client_socket != NULL) _udp_client_socket->SendPacket(&p, address);
|
||||
if (needs_mutex) _network_udp_mutex->EndCritical();
|
||||
}
|
||||
|
||||
/**
|
||||
* Threaded part for resolving the IP of a server and querying it.
|
||||
* @param pntr the NetworkUDPQueryServerInfo.
|
||||
*/
|
||||
static void NetworkUDPQueryServerThread(void *pntr)
|
||||
{
|
||||
NetworkUDPQueryServerInfo *info = (NetworkUDPQueryServerInfo*)pntr;
|
||||
NetworkUDPQueryServer(info, true, info->manually);
|
||||
|
||||
delete info;
|
||||
if (_udp_client_socket != NULL) _udp_client_socket->SendPacket(&p, &address);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -120,9 +93,8 @@ static void NetworkUDPQueryServerThread(void *pntr)
|
||||
*/
|
||||
void NetworkUDPQueryServer(NetworkAddress address, bool manually)
|
||||
{
|
||||
NetworkUDPQueryServerInfo *info = new NetworkUDPQueryServerInfo(address, manually);
|
||||
if (address.IsResolved() || !ThreadObject::New(NetworkUDPQueryServerThread, info, NULL, "ottd:udp-query")) {
|
||||
NetworkUDPQueryServerThread(info);
|
||||
if (address.IsResolved() || !StartNewThread(NULL, "ottd:udp-query", &DoNetworkUDPQueryServer, std::move(address), true, std::move(manually))) {
|
||||
DoNetworkUDPQueryServer(address, true, manually);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -510,7 +482,7 @@ void ClientNetworkUDPSocketHandler::Receive_MASTER_RESPONSE_LIST(Packet *p, Netw
|
||||
/* Somehow we reached the end of the packet */
|
||||
if (this->HasClientQuit()) return;
|
||||
|
||||
NetworkUDPQueryServer(&addr, false, false);
|
||||
DoNetworkUDPQueryServer(addr, false, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -616,9 +588,8 @@ void NetworkUDPSearchGame()
|
||||
|
||||
/**
|
||||
* Thread entry point for de-advertising.
|
||||
* @param pntr unused.
|
||||
*/
|
||||
static void NetworkUDPRemoveAdvertiseThread(void *pntr)
|
||||
static void NetworkUDPRemoveAdvertiseThread()
|
||||
{
|
||||
DEBUG(net, 1, "[udp] removing advertise from master server");
|
||||
|
||||
@@ -631,9 +602,8 @@ static void NetworkUDPRemoveAdvertiseThread(void *pntr)
|
||||
p.Send_uint8 (NETWORK_MASTER_SERVER_VERSION);
|
||||
p.Send_uint16(_settings_client.network.server_port);
|
||||
|
||||
_network_udp_mutex->BeginCritical();
|
||||
std::lock_guard<std::mutex> lock(_network_udp_mutex);
|
||||
if (_udp_master_socket != NULL) _udp_master_socket->SendPacket(&p, &out_addr, true);
|
||||
_network_udp_mutex->EndCritical();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -645,16 +615,15 @@ void NetworkUDPRemoveAdvertise(bool blocking)
|
||||
/* Check if we are advertising */
|
||||
if (!_networking || !_network_server || !_network_udp_server) return;
|
||||
|
||||
if (blocking || !ThreadObject::New(NetworkUDPRemoveAdvertiseThread, NULL, NULL, "ottd:udp-advert")) {
|
||||
NetworkUDPRemoveAdvertiseThread(NULL);
|
||||
if (blocking || !StartNewThread(NULL, "ottd:udp-advert", &NetworkUDPRemoveAdvertiseThread)) {
|
||||
NetworkUDPRemoveAdvertiseThread();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Thread entry point for advertising.
|
||||
* @param pntr unused.
|
||||
*/
|
||||
static void NetworkUDPAdvertiseThread(void *pntr)
|
||||
static void NetworkUDPAdvertiseThread()
|
||||
{
|
||||
/* Find somewhere to send */
|
||||
NetworkAddress out_addr(NETWORK_MASTER_SERVER_HOST, NETWORK_MASTER_SERVER_PORT);
|
||||
@@ -685,9 +654,8 @@ static void NetworkUDPAdvertiseThread(void *pntr)
|
||||
p.Send_uint16(_settings_client.network.server_port);
|
||||
p.Send_uint64(_session_key);
|
||||
|
||||
_network_udp_mutex->BeginCritical();
|
||||
std::lock_guard<std::mutex> lock(_network_udp_mutex);
|
||||
if (_udp_master_socket != NULL) _udp_master_socket->SendPacket(&p, &out_addr, true);
|
||||
_network_udp_mutex->EndCritical();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -728,8 +696,8 @@ void NetworkUDPAdvertise()
|
||||
if (_next_advertisement < _last_advertisement) _next_advertisement = UINT32_MAX;
|
||||
if (_next_retry < _last_advertisement) _next_retry = UINT32_MAX;
|
||||
|
||||
if (!ThreadObject::New(NetworkUDPAdvertiseThread, NULL, NULL, "ottd:udp-advert")) {
|
||||
NetworkUDPAdvertiseThread(NULL);
|
||||
if (!StartNewThread(NULL, "ottd:udp-advert", &NetworkUDPAdvertiseThread)) {
|
||||
NetworkUDPAdvertiseThread();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -742,7 +710,7 @@ void NetworkUDPInitialize()
|
||||
DEBUG(net, 1, "[udp] initializing listeners");
|
||||
assert(_udp_client_socket == NULL && _udp_server_socket == NULL && _udp_master_socket == NULL);
|
||||
|
||||
_network_udp_mutex->BeginCritical();
|
||||
std::lock_guard<std::mutex> lock(_network_udp_mutex);
|
||||
|
||||
_udp_client_socket = new ClientNetworkUDPSocketHandler();
|
||||
|
||||
@@ -756,13 +724,12 @@ void NetworkUDPInitialize()
|
||||
|
||||
_network_udp_server = false;
|
||||
_network_udp_broadcast = 0;
|
||||
_network_udp_mutex->EndCritical();
|
||||
}
|
||||
|
||||
/** Close all UDP related stuff. */
|
||||
void NetworkUDPClose()
|
||||
{
|
||||
_network_udp_mutex->BeginCritical();
|
||||
std::lock_guard<std::mutex> lock(_network_udp_mutex);
|
||||
_udp_server_socket->Close();
|
||||
_udp_master_socket->Close();
|
||||
_udp_client_socket->Close();
|
||||
@@ -772,7 +739,6 @@ void NetworkUDPClose()
|
||||
_udp_client_socket = NULL;
|
||||
_udp_server_socket = NULL;
|
||||
_udp_master_socket = NULL;
|
||||
_network_udp_mutex->EndCritical();
|
||||
|
||||
_network_udp_server = false;
|
||||
_network_udp_broadcast = 0;
|
||||
@@ -782,7 +748,7 @@ void NetworkUDPClose()
|
||||
/** Receive the UDP packets. */
|
||||
void NetworkBackgroundUDPLoop()
|
||||
{
|
||||
_network_udp_mutex->BeginCritical();
|
||||
std::lock_guard<std::mutex> lock(_network_udp_mutex);
|
||||
|
||||
if (_network_udp_server) {
|
||||
_udp_server_socket->ReceivePackets();
|
||||
@@ -791,6 +757,4 @@ void NetworkBackgroundUDPLoop()
|
||||
_udp_client_socket->ReceivePackets();
|
||||
if (_network_udp_broadcast > 0) _network_udp_broadcast--;
|
||||
}
|
||||
|
||||
_network_udp_mutex->EndCritical();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user