forked from Mirrorlandia_minetest/minetest
Clean up ClientInterface locking
This commit is contained in:
parent
d387e9b6d3
commit
1c73902005
@ -27,6 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "network/networkprotocol.h"
|
#include "network/networkprotocol.h"
|
||||||
#include "network/address.h"
|
#include "network/address.h"
|
||||||
#include "porting.h"
|
#include "porting.h"
|
||||||
|
#include "threading/mutex_auto_lock.h"
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -503,9 +504,13 @@ public:
|
|||||||
|
|
||||||
static std::string state2Name(ClientState state);
|
static std::string state2Name(ClientState state);
|
||||||
protected:
|
protected:
|
||||||
//TODO find way to avoid this functions
|
class AutoLock {
|
||||||
void lock() { m_clients_mutex.lock(); }
|
public:
|
||||||
void unlock() { m_clients_mutex.unlock(); }
|
AutoLock(ClientInterface &iface): m_lock(iface.m_clients_mutex) {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
RecursiveMutexAutoLock m_lock;
|
||||||
|
};
|
||||||
|
|
||||||
RemoteClientMap& getClientList() { return m_clients; }
|
RemoteClientMap& getClientList() { return m_clients; }
|
||||||
|
|
||||||
|
@ -452,7 +452,7 @@ void Server::handleCommand_GotBlocks(NetworkPacket* pkt)
|
|||||||
("GOTBLOCKS length is too short");
|
("GOTBLOCKS length is too short");
|
||||||
}
|
}
|
||||||
|
|
||||||
m_clients.lock();
|
ClientInterface::AutoLock lock(m_clients);
|
||||||
RemoteClient *client = m_clients.lockedGetClientNoEx(pkt->getPeerId());
|
RemoteClient *client = m_clients.lockedGetClientNoEx(pkt->getPeerId());
|
||||||
|
|
||||||
for (u16 i = 0; i < count; i++) {
|
for (u16 i = 0; i < count; i++) {
|
||||||
@ -460,7 +460,6 @@ void Server::handleCommand_GotBlocks(NetworkPacket* pkt)
|
|||||||
*pkt >> p;
|
*pkt >> p;
|
||||||
client->GotBlock(p);
|
client->GotBlock(p);
|
||||||
}
|
}
|
||||||
m_clients.unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::process_PlayerPos(RemotePlayer *player, PlayerSAO *playersao,
|
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;
|
//infostream<<"Server: Checking added and deleted active objects"<<std::endl;
|
||||||
MutexAutoLock envlock(m_env_mutex);
|
MutexAutoLock envlock(m_env_mutex);
|
||||||
|
|
||||||
m_clients.lock();
|
{
|
||||||
|
ClientInterface::AutoLock clientlock(m_clients);
|
||||||
const RemoteClientMap &clients = m_clients.getClientList();
|
const RemoteClientMap &clients = m_clients.getClientList();
|
||||||
ScopeProfiler sp(g_profiler, "Server: update objects within range");
|
ScopeProfiler sp(g_profiler, "Server: update objects within range");
|
||||||
|
|
||||||
@ -744,7 +745,7 @@ void Server::AsyncRunStep(bool initial_step)
|
|||||||
|
|
||||||
SendActiveObjectRemoveAdd(client, playersao);
|
SendActiveObjectRemoveAdd(client, playersao);
|
||||||
}
|
}
|
||||||
m_clients.unlock();
|
}
|
||||||
|
|
||||||
// Write changes to the mod storage
|
// Write changes to the mod storage
|
||||||
m_mod_storage_save_timer -= dtime;
|
m_mod_storage_save_timer -= dtime;
|
||||||
@ -787,7 +788,8 @@ void Server::AsyncRunStep(bool initial_step)
|
|||||||
|
|
||||||
m_aom_buffer_counter->increment(aom_count);
|
m_aom_buffer_counter->increment(aom_count);
|
||||||
|
|
||||||
m_clients.lock();
|
{
|
||||||
|
ClientInterface::AutoLock clientlock(m_clients);
|
||||||
const RemoteClientMap &clients = m_clients.getClientList();
|
const RemoteClientMap &clients = m_clients.getClientList();
|
||||||
// Route data to every client
|
// Route data to every client
|
||||||
std::string reliable_data, unreliable_data;
|
std::string reliable_data, unreliable_data;
|
||||||
@ -843,7 +845,7 @@ void Server::AsyncRunStep(bool initial_step)
|
|||||||
SendActiveObjectMessages(client->peer_id, unreliable_data, false);
|
SendActiveObjectMessages(client->peer_id, unreliable_data, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_clients.unlock();
|
}
|
||||||
|
|
||||||
// Clear buffered_messages
|
// Clear buffered_messages
|
||||||
for (auto &buffered_message : buffered_messages) {
|
for (auto &buffered_message : buffered_messages) {
|
||||||
@ -1050,18 +1052,14 @@ PlayerSAO* Server::StageTwoClientInit(session_t peer_id)
|
|||||||
{
|
{
|
||||||
std::string playername;
|
std::string playername;
|
||||||
PlayerSAO *playersao = NULL;
|
PlayerSAO *playersao = NULL;
|
||||||
m_clients.lock();
|
{
|
||||||
try {
|
ClientInterface::AutoLock clientlock(m_clients);
|
||||||
RemoteClient* client = m_clients.lockedGetClientNoEx(peer_id, CS_InitDone);
|
RemoteClient* client = m_clients.lockedGetClientNoEx(peer_id, CS_InitDone);
|
||||||
if (client) {
|
if (client) {
|
||||||
playername = client->getName();
|
playername = client->getName();
|
||||||
playersao = emergePlayer(playername.c_str(), peer_id, client->net_proto_version);
|
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());
|
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)
|
void Server::SetBlocksNotSent(std::map<v3s16, MapBlock *>& block)
|
||||||
{
|
{
|
||||||
std::vector<session_t> clients = m_clients.getClientIDs();
|
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
|
// Set the modified blocks unsent for all the clients
|
||||||
for (const session_t client_id : clients) {
|
for (const session_t client_id : clients) {
|
||||||
if (RemoteClient *client = m_clients.lockedGetClientNoEx(client_id))
|
if (RemoteClient *client = m_clients.lockedGetClientNoEx(client_id))
|
||||||
client->SetBlocksNotSent(block);
|
client->SetBlocksNotSent(block);
|
||||||
}
|
}
|
||||||
m_clients.unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::peerAdded(con::Peer *peer)
|
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)
|
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);
|
RemoteClient* client = m_clients.lockedGetClientNoEx(peer_id, CS_Invalid);
|
||||||
|
|
||||||
if (!client) {
|
if (!client)
|
||||||
m_clients.unlock();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
ret.state = client->getState();
|
ret.state = client->getState();
|
||||||
ret.addr = client->getAddress();
|
ret.addr = client->getAddress();
|
||||||
@ -1288,8 +1283,6 @@ bool Server::getClientInfo(session_t peer_id, ClientInfo &ret)
|
|||||||
|
|
||||||
ret.lang_code = client->getLangCode();
|
ret.lang_code = client->getLangCode();
|
||||||
|
|
||||||
m_clients.unlock();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2218,7 +2211,7 @@ void Server::sendRemoveNode(v3s16 p, std::unordered_set<u16> *far_players,
|
|||||||
pkt << p;
|
pkt << p;
|
||||||
|
|
||||||
std::vector<session_t> clients = m_clients.getClientIDs();
|
std::vector<session_t> clients = m_clients.getClientIDs();
|
||||||
m_clients.lock();
|
ClientInterface::AutoLock clientlock(m_clients);
|
||||||
|
|
||||||
for (session_t client_id : clients) {
|
for (session_t client_id : clients) {
|
||||||
RemoteClient *client = m_clients.lockedGetClientNoEx(client_id);
|
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
|
// Send as reliable
|
||||||
m_clients.send(client_id, 0, &pkt, true);
|
m_clients.send(client_id, 0, &pkt, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_clients.unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::sendAddNode(v3s16 p, MapNode n, std::unordered_set<u16> *far_players,
|
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);
|
<< (u8) (remove_metadata ? 0 : 1);
|
||||||
|
|
||||||
std::vector<session_t> clients = m_clients.getClientIDs();
|
std::vector<session_t> clients = m_clients.getClientIDs();
|
||||||
m_clients.lock();
|
ClientInterface::AutoLock clientlock(m_clients);
|
||||||
|
|
||||||
for (session_t client_id : clients) {
|
for (session_t client_id : clients) {
|
||||||
RemoteClient *client = m_clients.lockedGetClientNoEx(client_id);
|
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
|
// Send as reliable
|
||||||
m_clients.send(client_id, 0, &pkt, true);
|
m_clients.send(client_id, 0, &pkt, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_clients.unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::sendMetadataChanged(const std::list<v3s16> &meta_updates, float far_d_nodes)
|
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);
|
NodeMetadataList meta_updates_list(false);
|
||||||
std::vector<session_t> clients = m_clients.getClientIDs();
|
std::vector<session_t> clients = m_clients.getClientIDs();
|
||||||
|
|
||||||
m_clients.lock();
|
ClientInterface::AutoLock clientlock(m_clients);
|
||||||
|
|
||||||
for (session_t i : clients) {
|
for (session_t i : clients) {
|
||||||
RemoteClient *client = m_clients.lockedGetClientNoEx(i);
|
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();
|
meta_updates_list.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_clients.unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::SendBlockNoLock(session_t peer_id, MapBlock *block, u8 ver,
|
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();
|
std::vector<session_t> clients = m_clients.getClientIDs();
|
||||||
|
|
||||||
m_clients.lock();
|
ClientInterface::AutoLock clientlock(m_clients);
|
||||||
for (const session_t client_id : clients) {
|
for (const session_t client_id : clients) {
|
||||||
RemoteClient *client = m_clients.lockedGetClientNoEx(client_id, CS_Active);
|
RemoteClient *client = m_clients.lockedGetClientNoEx(client_id, CS_Active);
|
||||||
|
|
||||||
@ -2378,7 +2365,6 @@ void Server::SendBlocks(float dtime)
|
|||||||
total_sending += client->getSendingCount();
|
total_sending += client->getSendingCount();
|
||||||
client->GetNextBlocks(m_env,m_emerge, dtime, queue);
|
client->GetNextBlocks(m_env,m_emerge, dtime, queue);
|
||||||
}
|
}
|
||||||
m_clients.unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort.
|
// Sort.
|
||||||
@ -2386,7 +2372,7 @@ void Server::SendBlocks(float dtime)
|
|||||||
// Lowest is most important.
|
// Lowest is most important.
|
||||||
std::sort(queue.begin(), queue.end());
|
std::sort(queue.begin(), queue.end());
|
||||||
|
|
||||||
m_clients.lock();
|
ClientInterface::AutoLock clientlock(m_clients);
|
||||||
|
|
||||||
// Maximal total count calculation
|
// Maximal total count calculation
|
||||||
// The per-client block sends is halved with the maximal online users
|
// 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);
|
client->SentBlock(block_to_send.pos);
|
||||||
total_sending++;
|
total_sending++;
|
||||||
}
|
}
|
||||||
m_clients.unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Server::SendBlock(session_t peer_id, const v3s16 &blockpos)
|
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)
|
if (!block)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
m_clients.lock();
|
ClientInterface::AutoLock clientlock(m_clients);
|
||||||
RemoteClient *client = m_clients.lockedGetClientNoEx(peer_id, CS_Active);
|
RemoteClient *client = m_clients.lockedGetClientNoEx(peer_id, CS_Active);
|
||||||
if (!client || client->isBlockSent(blockpos)) {
|
if (!client || client->isBlockSent(blockpos))
|
||||||
m_clients.unlock();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
SendBlockNoLock(peer_id, block, client->serialization_version,
|
SendBlockNoLock(peer_id, block, client->serialization_version,
|
||||||
client->net_proto_version);
|
client->net_proto_version);
|
||||||
m_clients.unlock();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -3534,7 +3516,8 @@ bool Server::dynamicAddMedia(std::string filepath,
|
|||||||
legacy_pkt.putLongString(filedata);
|
legacy_pkt.putLongString(filedata);
|
||||||
|
|
||||||
std::unordered_set<session_t> delivered, waiting;
|
std::unordered_set<session_t> delivered, waiting;
|
||||||
m_clients.lock();
|
{
|
||||||
|
ClientInterface::AutoLock clientlock(m_clients);
|
||||||
for (auto &pair : m_clients.getClientList()) {
|
for (auto &pair : m_clients.getClientList()) {
|
||||||
if (pair.second->getState() == CS_DefinitionsSent && !ephemeral) {
|
if (pair.second->getState() == CS_DefinitionsSent && !ephemeral) {
|
||||||
/*
|
/*
|
||||||
@ -3575,7 +3558,7 @@ bool Server::dynamicAddMedia(std::string filepath,
|
|||||||
Send(peer_id, &pkt);
|
Send(peer_id, &pkt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_clients.unlock();
|
}
|
||||||
|
|
||||||
// Run callback for players that already had the file delivered (legacy-only)
|
// Run callback for players that already had the file delivered (legacy-only)
|
||||||
for (session_t peer_id : delivered) {
|
for (session_t peer_id : delivered) {
|
||||||
|
Loading…
Reference in New Issue
Block a user