From 05f4e7360886e36b221ef5c3af4426625a3de686 Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Mon, 11 Mar 2019 00:45:39 +0100 Subject: Codechange: Replace custom mutex code with C++11 mutex'es. A conforming compiler with a valid -header is expected. Most parts of the code assume that locking a mutex will never fail unexpectedly, which is generally true on all common platforms that don't just pretend to be C++11. The use of condition variables in driver code is checked. --- src/network/network_gamelist.cpp | 10 ++++------ src/network/network_server.cpp | 36 ++++++++++++------------------------ src/network/network_udp.cpp | 23 +++++++++-------------- 3 files changed, 25 insertions(+), 44 deletions(-) (limited to 'src/network') diff --git a/src/network/network_gamelist.cpp b/src/network/network_gamelist.cpp index 6c65c52c9..c67fba5ec 100644 --- a/src/network/network_gamelist.cpp +++ b/src/network/network_gamelist.cpp @@ -15,17 +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 #include "../safeguards.h" NetworkGameList *_network_game_list = NULL; /** Mutex for handling delayed insertion/querying of servers. */ -static ThreadMutex *_network_game_list_mutex = ThreadMutex::New(); +static std::mutex _network_game_list_mutex; /** The games to insert when the GUI thread has time for us. */ static NetworkGameList *_network_game_delayed_insertion_list = NULL; @@ -36,16 +36,15 @@ static NetworkGameList *_network_game_delayed_insertion_list = NULL; */ void NetworkGameListAddItemDelayed(NetworkGameList *item) { - _network_game_list_mutex->BeginCritical(); + std::lock_guard lock(_network_game_list_mutex); item->next = _network_game_delayed_insertion_list; _network_game_delayed_insertion_list = item; - _network_game_list_mutex->EndCritical(); } /** Perform the delayed (thread safe) insertion into the game list */ static void NetworkGameListHandleDelayedInsert() { - _network_game_list_mutex->BeginCritical(); + std::lock_guard lock(_network_game_list_mutex); while (_network_game_delayed_insertion_list != NULL) { NetworkGameList *ins_item = _network_game_delayed_insertion_list; _network_game_delayed_insertion_list = ins_item->next; @@ -66,7 +65,6 @@ static void NetworkGameListHandleDelayedInsert() } free(ins_item); } - _network_game_list_mutex->EndCritical(); } /** diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp index 1bcd7ca12..97da64bd3 100644 --- a/src/network/network_server.cpp +++ b/src/network/network_server.cpp @@ -30,6 +30,8 @@ #include "../core/pool_func.hpp" #include "../core/random_func.hpp" #include "../rev.h" +#include +#include #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 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 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 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 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 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(); } }; diff --git a/src/network/network_udp.cpp b/src/network/network_udp.cpp index 2d7ee2d3c..df8c59aac 100644 --- a/src/network/network_udp.cpp +++ b/src/network/network_udp.cpp @@ -29,13 +29,14 @@ #include "../newgrf_text.h" #include "../strings_func.h" #include "table/strings.h" +#include #include "core/udp.h" #include "../safeguards.h" /** 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; @@ -80,11 +81,11 @@ static void NetworkUDPQueryServer(NetworkAddress *address, bool needs_mutex, boo item->manually = manually; NetworkGameListAddItemDelayed(item); - if (needs_mutex) _network_udp_mutex->BeginCritical(); + std::unique_lock lock(_network_udp_mutex, std::defer_lock); + if (needs_mutex) lock.lock(); /* 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(); } /** @@ -549,9 +550,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 lock(_network_udp_mutex); if (_udp_master_socket != NULL) _udp_master_socket->SendPacket(&p, &out_addr, true); - _network_udp_mutex->EndCritical(); } /** @@ -603,9 +603,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 lock(_network_udp_mutex); if (_udp_master_socket != NULL) _udp_master_socket->SendPacket(&p, &out_addr, true); - _network_udp_mutex->EndCritical(); } /** @@ -660,7 +659,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 lock(_network_udp_mutex); _udp_client_socket = new ClientNetworkUDPSocketHandler(); @@ -674,13 +673,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 lock(_network_udp_mutex); _udp_server_socket->Close(); _udp_master_socket->Close(); _udp_client_socket->Close(); @@ -690,7 +688,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; @@ -700,7 +697,7 @@ void NetworkUDPClose() /** Receive the UDP packets. */ void NetworkBackgroundUDPLoop() { - _network_udp_mutex->BeginCritical(); + std::lock_guard lock(_network_udp_mutex); if (_network_udp_server) { _udp_server_socket->ReceivePackets(); @@ -709,6 +706,4 @@ void NetworkBackgroundUDPLoop() _udp_client_socket->ReceivePackets(); if (_network_udp_broadcast > 0) _network_udp_broadcast--; } - - _network_udp_mutex->EndCritical(); } -- cgit v1.2.3-70-g09d2