mirror of https://github.com/OpenTTD/OpenTTD
(svn r23754) -Fix (r23752): the locks aren't reentrant
parent
d0770c8319
commit
d2c643df63
|
@ -48,6 +48,70 @@ NetworkUDPSocketHandler *_udp_client_socket = NULL; ///< udp client socket
|
||||||
NetworkUDPSocketHandler *_udp_server_socket = NULL; ///< udp server socket
|
NetworkUDPSocketHandler *_udp_server_socket = NULL; ///< udp server socket
|
||||||
NetworkUDPSocketHandler *_udp_master_socket = NULL; ///< udp master 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)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function doing the actual work for querying the server.
|
||||||
|
* @param address The address of the server.
|
||||||
|
* @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)
|
||||||
|
{
|
||||||
|
/* 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;
|
||||||
|
item->manually = manually;
|
||||||
|
NetworkGameListAddItemDelayed(item);
|
||||||
|
|
||||||
|
if (needs_mutex) _network_udp_mutex->BeginCritical();
|
||||||
|
/* Init the packet */
|
||||||
|
Packet p(PACKET_UDP_CLIENT_FIND_SERVER);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Query a specific server.
|
||||||
|
* @param address The address of the server.
|
||||||
|
* @param manually Whether the address was entered manually.
|
||||||
|
*/
|
||||||
|
void NetworkUDPQueryServer(NetworkAddress address, bool manually)
|
||||||
|
{
|
||||||
|
NetworkUDPQueryServerInfo *info = new NetworkUDPQueryServerInfo(address, manually);
|
||||||
|
if (address.IsResolved() || !ThreadObject::New(NetworkUDPQueryServerThread, info)) {
|
||||||
|
NetworkUDPQueryServerThread(info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
///*** Communication with the masterserver ***/
|
///*** Communication with the masterserver ***/
|
||||||
|
|
||||||
/** Helper class for connecting to the master server. */
|
/** Helper class for connecting to the master server. */
|
||||||
|
@ -364,7 +428,7 @@ void ClientNetworkUDPSocketHandler::Receive_MASTER_RESPONSE_LIST(Packet *p, Netw
|
||||||
/* Somehow we reached the end of the packet */
|
/* Somehow we reached the end of the packet */
|
||||||
if (this->HasClientQuit()) return;
|
if (this->HasClientQuit()) return;
|
||||||
|
|
||||||
NetworkUDPQueryServer(addr);
|
NetworkUDPQueryServer(&addr, false, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -468,60 +532,6 @@ void NetworkUDPSearchGame()
|
||||||
_network_udp_broadcast = 300; // Stay searching for 300 ticks
|
_network_udp_broadcast = 300; // Stay searching for 300 ticks
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 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)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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;
|
|
||||||
|
|
||||||
/* Clear item in gamelist */
|
|
||||||
NetworkGameList *item = CallocT<NetworkGameList>(1);
|
|
||||||
info->GetAddressAsString(item->info.server_name, lastof(item->info.server_name));
|
|
||||||
strecpy(item->info.hostname, info->GetHostname(), lastof(item->info.hostname));
|
|
||||||
item->address = *info;
|
|
||||||
item->manually = info->manually;
|
|
||||||
NetworkGameListAddItemDelayed(item);
|
|
||||||
|
|
||||||
_network_udp_mutex->BeginCritical();
|
|
||||||
/* Init the packet */
|
|
||||||
Packet p(PACKET_UDP_CLIENT_FIND_SERVER);
|
|
||||||
if (_udp_client_socket != NULL) _udp_client_socket->SendPacket(&p, info);
|
|
||||||
_network_udp_mutex->EndCritical();
|
|
||||||
|
|
||||||
delete info;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Query a specific server.
|
|
||||||
* @param address The address of the server.
|
|
||||||
* @param manually Whether the address was entered manually.
|
|
||||||
*/
|
|
||||||
void NetworkUDPQueryServer(NetworkAddress address, bool manually)
|
|
||||||
{
|
|
||||||
NetworkUDPQueryServerInfo *info = new NetworkUDPQueryServerInfo(address, manually);
|
|
||||||
if (address.IsResolved() || !ThreadObject::New(NetworkUDPQueryServerThread, info)) {
|
|
||||||
NetworkUDPQueryServerThread(info);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thread entry point for de-advertising.
|
* Thread entry point for de-advertising.
|
||||||
* @param pntr unused.
|
* @param pntr unused.
|
||||||
|
|
Loading…
Reference in New Issue