Clean up ClientInterface locking

This commit is contained in:
Jude Melton-Houghton 2022-02-01 20:49:19 -05:00 committed by sfan5
parent d387e9b6d3
commit 1c73902005
3 changed files with 127 additions and 140 deletions

@ -27,6 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "network/networkprotocol.h"
#include "network/address.h"
#include "porting.h"
#include "threading/mutex_auto_lock.h"
#include <list>
#include <vector>
@ -503,9 +504,13 @@ public:
static std::string state2Name(ClientState state);
protected:
//TODO find way to avoid this functions
void lock() { m_clients_mutex.lock(); }
void unlock() { m_clients_mutex.unlock(); }
class AutoLock {
public:
AutoLock(ClientInterface &iface): m_lock(iface.m_clients_mutex) {}
private:
RecursiveMutexAutoLock m_lock;
};
RemoteClientMap& getClientList() { return m_clients; }

@ -452,7 +452,7 @@ void Server::handleCommand_GotBlocks(NetworkPacket* pkt)
("GOTBLOCKS length is too short");
}
m_clients.lock();
ClientInterface::AutoLock lock(m_clients);
RemoteClient *client = m_clients.lockedGetClientNoEx(pkt->getPeerId());
for (u16 i = 0; i < count; i++) {
@ -460,7 +460,6 @@ void Server::handleCommand_GotBlocks(NetworkPacket* pkt)
*pkt >> p;
client->GotBlock(p);
}
m_clients.unlock();
}
void Server::process_PlayerPos(RemotePlayer *player, PlayerSAO *playersao,

@ -723,7 +723,8 @@ void Server::AsyncRunStep(bool initial_step)
//infostream<<"Server: Checking added and deleted active objects"<<std::endl;
MutexAutoLock envlock(m_env_mutex);
m_clients.lock();
{
ClientInterface::AutoLock clientlock(m_clients);
const RemoteClientMap &clients = m_clients.getClientList();
ScopeProfiler sp(g_profiler, "Server: update objects within range");
@ -744,7 +745,7 @@ void Server::AsyncRunStep(bool initial_step)
SendActiveObjectRemoveAdd(client, playersao);
}
m_clients.unlock();
}
// Write changes to the mod storage
m_mod_storage_save_timer -= dtime;
@ -787,7 +788,8 @@ void Server::AsyncRunStep(bool initial_step)
m_aom_buffer_counter->increment(aom_count);
m_clients.lock();
{
ClientInterface::AutoLock clientlock(m_clients);
const RemoteClientMap &clients = m_clients.getClientList();
// Route data to every client
std::string reliable_data, unreliable_data;
@ -843,7 +845,7 @@ void Server::AsyncRunStep(bool initial_step)
SendActiveObjectMessages(client->peer_id, unreliable_data, false);
}
}
m_clients.unlock();
}
// Clear buffered_messages
for (auto &buffered_message : buffered_messages) {
@ -1050,18 +1052,14 @@ PlayerSAO* Server::StageTwoClientInit(session_t peer_id)
{
std::string playername;
PlayerSAO *playersao = NULL;
m_clients.lock();
try {
{
ClientInterface::AutoLock clientlock(m_clients);
RemoteClient* client = m_clients.lockedGetClientNoEx(peer_id, CS_InitDone);
if (client) {
playername = client->getName();
playersao = emergePlayer(playername.c_str(), peer_id, client->net_proto_version);
}
} catch (std::exception &e) {
m_clients.unlock();
throw;
}
m_clients.unlock();
RemotePlayer *player = m_env->getPlayer(playername.c_str());
@ -1233,13 +1231,12 @@ void Server::onMapEditEvent(const MapEditEvent &event)
void Server::SetBlocksNotSent(std::map<v3s16, MapBlock *>& block)
{
std::vector<session_t> clients = m_clients.getClientIDs();
m_clients.lock();
ClientInterface::AutoLock clientlock(m_clients);
// Set the modified blocks unsent for all the clients
for (const session_t client_id : clients) {
if (RemoteClient *client = m_clients.lockedGetClientNoEx(client_id))
client->SetBlocksNotSent(block);
}
m_clients.unlock();
}
void Server::peerAdded(con::Peer *peer)
@ -1267,13 +1264,11 @@ bool Server::getClientConInfo(session_t peer_id, con::rtt_stat_type type, float*
bool Server::getClientInfo(session_t peer_id, ClientInfo &ret)
{
m_clients.lock();
ClientInterface::AutoLock clientlock(m_clients);
RemoteClient* client = m_clients.lockedGetClientNoEx(peer_id, CS_Invalid);
if (!client) {
m_clients.unlock();
if (!client)
return false;
}
ret.state = client->getState();
ret.addr = client->getAddress();
@ -1288,8 +1283,6 @@ bool Server::getClientInfo(session_t peer_id, ClientInfo &ret)
ret.lang_code = client->getLangCode();
m_clients.unlock();
return true;
}
@ -2218,7 +2211,7 @@ void Server::sendRemoveNode(v3s16 p, std::unordered_set<u16> *far_players,
pkt << p;
std::vector<session_t> clients = m_clients.getClientIDs();
m_clients.lock();
ClientInterface::AutoLock clientlock(m_clients);
for (session_t client_id : clients) {
RemoteClient *client = m_clients.lockedGetClientNoEx(client_id);
@ -2241,8 +2234,6 @@ void Server::sendRemoveNode(v3s16 p, std::unordered_set<u16> *far_players,
// Send as reliable
m_clients.send(client_id, 0, &pkt, true);
}
m_clients.unlock();
}
void Server::sendAddNode(v3s16 p, MapNode n, std::unordered_set<u16> *far_players,
@ -2257,7 +2248,7 @@ void Server::sendAddNode(v3s16 p, MapNode n, std::unordered_set<u16> *far_player
<< (u8) (remove_metadata ? 0 : 1);
std::vector<session_t> clients = m_clients.getClientIDs();
m_clients.lock();
ClientInterface::AutoLock clientlock(m_clients);
for (session_t client_id : clients) {
RemoteClient *client = m_clients.lockedGetClientNoEx(client_id);
@ -2280,8 +2271,6 @@ void Server::sendAddNode(v3s16 p, MapNode n, std::unordered_set<u16> *far_player
// Send as reliable
m_clients.send(client_id, 0, &pkt, true);
}
m_clients.unlock();
}
void Server::sendMetadataChanged(const std::list<v3s16> &meta_updates, float far_d_nodes)
@ -2290,7 +2279,7 @@ void Server::sendMetadataChanged(const std::list<v3s16> &meta_updates, float far
NodeMetadataList meta_updates_list(false);
std::vector<session_t> clients = m_clients.getClientIDs();
m_clients.lock();
ClientInterface::AutoLock clientlock(m_clients);
for (session_t i : clients) {
RemoteClient *client = m_clients.lockedGetClientNoEx(i);
@ -2331,8 +2320,6 @@ void Server::sendMetadataChanged(const std::list<v3s16> &meta_updates, float far
meta_updates_list.clear();
}
m_clients.unlock();
}
void Server::SendBlockNoLock(session_t peer_id, MapBlock *block, u8 ver,
@ -2368,7 +2355,7 @@ void Server::SendBlocks(float dtime)
std::vector<session_t> clients = m_clients.getClientIDs();
m_clients.lock();
ClientInterface::AutoLock clientlock(m_clients);
for (const session_t client_id : clients) {
RemoteClient *client = m_clients.lockedGetClientNoEx(client_id, CS_Active);
@ -2378,7 +2365,6 @@ void Server::SendBlocks(float dtime)
total_sending += client->getSendingCount();
client->GetNextBlocks(m_env,m_emerge, dtime, queue);
}
m_clients.unlock();
}
// Sort.
@ -2386,7 +2372,7 @@ void Server::SendBlocks(float dtime)
// Lowest is most important.
std::sort(queue.begin(), queue.end());
m_clients.lock();
ClientInterface::AutoLock clientlock(m_clients);
// Maximal total count calculation
// The per-client block sends is halved with the maximal online users
@ -2415,7 +2401,6 @@ void Server::SendBlocks(float dtime)
client->SentBlock(block_to_send.pos);
total_sending++;
}
m_clients.unlock();
}
bool Server::SendBlock(session_t peer_id, const v3s16 &blockpos)
@ -2424,15 +2409,12 @@ bool Server::SendBlock(session_t peer_id, const v3s16 &blockpos)
if (!block)
return false;
m_clients.lock();
ClientInterface::AutoLock clientlock(m_clients);
RemoteClient *client = m_clients.lockedGetClientNoEx(peer_id, CS_Active);
if (!client || client->isBlockSent(blockpos)) {
m_clients.unlock();
if (!client || client->isBlockSent(blockpos))
return false;
}
SendBlockNoLock(peer_id, block, client->serialization_version,
client->net_proto_version);
m_clients.unlock();
return true;
}
@ -3534,7 +3516,8 @@ bool Server::dynamicAddMedia(std::string filepath,
legacy_pkt.putLongString(filedata);
std::unordered_set<session_t> delivered, waiting;
m_clients.lock();
{
ClientInterface::AutoLock clientlock(m_clients);
for (auto &pair : m_clients.getClientList()) {
if (pair.second->getState() == CS_DefinitionsSent && !ephemeral) {
/*
@ -3575,7 +3558,7 @@ bool Server::dynamicAddMedia(std::string filepath,
Send(peer_id, &pkt);
}
}
m_clients.unlock();
}
// Run callback for players that already had the file delivered (legacy-only)
for (session_t peer_id : delivered) {