Decreased the scope of read mutex

This commit is contained in:
Anonymous-275 2021-03-31 00:05:05 +03:00
parent 24994d7dde
commit f323d50e34
6 changed files with 97 additions and 64 deletions

View File

@ -26,7 +26,7 @@ public:
static void GlobalParser(const std::weak_ptr<TClient>& Client, std::string Packet, TPPSMonitor& PPSMonitor, TNetwork& Network);
static void HandleEvent(TClient& c, const std::string& Data);
RWMutex& GetClientMutex() const { return mClientsMutex; }
private:
TClientSet mClients;
mutable RWMutex mClientsMutex;

View File

@ -99,6 +99,7 @@ THeartbeatThread::THeartbeatThread(TResourceManager& ResourceManager, TServer& S
std::string THeartbeatThread::GetPlayers() {
std::string Return;
mServer.ForEachClient([&](const std::weak_ptr<TClient>& ClientPtr) -> bool {
ReadLock Lock(mServer.GetClientMutex());
if (!ClientPtr.expired()) {
Return += ClientPtr.lock()->GetName() + ";";
}

View File

@ -233,6 +233,7 @@ int lua_Sleep(lua_State* L) {
std::optional<std::weak_ptr<TClient>> GetClient(TServer& Server, int ID) {
std::optional<std::weak_ptr<TClient>> MaybeClient { std::nullopt };
Server.ForEachClient([&](std::weak_ptr<TClient> CPtr) -> bool {
ReadLock Lock(Server.GetClientMutex());
if (!CPtr.expired()) {
auto C = CPtr.lock();
if (C->GetID() == ID) {
@ -294,9 +295,13 @@ int lua_GetGuest(lua_State* L) {
int lua_GetAllPlayers(lua_State* L) {
lua_newtable(L);
Engine().Server().ForEachClient([&](const std::weak_ptr<TClient>& ClientPtr) -> bool {
std::shared_ptr<TClient> Client;
{
ReadLock Lock(Engine().Server().GetClientMutex());
if (ClientPtr.expired())
return true;
auto Client = ClientPtr.lock();
Client = ClientPtr.lock();
}
lua_pushinteger(L, Client->GetID());
lua_pushstring(L, Client->GetName().c_str());
lua_settable(L, -3);

View File

@ -83,15 +83,21 @@ void TNetwork::UDPServerMain() {
inet_ntop(AF_INET, &client.sin_addr, clientIp, 256);*/
uint8_t ID = uint8_t(Data.at(0)) - 1;
mServer.ForEachClient([&](std::weak_ptr<TClient> ClientPtr) -> bool {
std::shared_ptr<TClient> Client;
{
ReadLock Lock(mServer.GetClientMutex());
if (!ClientPtr.expired()) {
auto Client = ClientPtr.lock();
Client = ClientPtr.lock();
}else return true;
}
if (Client->GetID() == ID) {
Client->UpdatePingTime();
Client->SetUDPAddr(client);
Client->SetIsConnected(true);
TServer::GlobalParser(ClientPtr, Data.substr(2), mPPSMonitor, *this);
}
}
return true;
});
} catch (const std::exception& e) {
@ -227,6 +233,7 @@ void TNetwork::HandleDownload(SOCKET TCPSock) {
}
auto ID = uint8_t(D);
mServer.ForEachClient([&](const std::weak_ptr<TClient>& ClientPtr) -> bool {
ReadLock Lock(mServer.GetClientMutex());
if (!ClientPtr.expired()) {
auto c = ClientPtr.lock();
if (c->GetID() == ID) {
@ -300,8 +307,13 @@ void TNetwork::Authentication(SOCKET TCPSock) {
debug("Name -> " + Client->GetName() + ", Guest -> " + std::to_string(Client->IsGuest()) + ", Roles -> " + Client->GetRoles());
debug("There are " + std::to_string(mServer.ClientCount()) + " known clients");
mServer.ForEachClient([&](const std::weak_ptr<TClient>& ClientPtr) -> bool {
std::shared_ptr<TClient> Cl;
{
ReadLock Lock(mServer.GetClientMutex());
if (!ClientPtr.expired()) {
auto Cl = ClientPtr.lock();
Cl = ClientPtr.lock();
} else return true;
}
info("Client Iteration: Name -> " + Cl->GetName() + ", Guest -> " + std::to_string(Cl->IsGuest()) + ", Roles -> " + Cl->GetRoles());
if (Cl->GetName() == Client->GetName() && Cl->IsGuest() == Client->IsGuest()) {
info("New client matched with current iteration");
@ -310,7 +322,7 @@ void TNetwork::Authentication(SOCKET TCPSock) {
Cl->SetStatus(-2);
return false;
}
}
return true;
});
@ -531,6 +543,7 @@ void TNetwork::TCPClient(const std::weak_ptr<TClient>& c) {
void TNetwork::UpdatePlayer(TClient& Client) {
std::string Packet = ("Ss") + std::to_string(mServer.ClientCount()) + "/" + std::to_string(Application::Settings.MaxPlayers) + ":";
mServer.ForEachClient([&](const std::weak_ptr<TClient>& ClientPtr) -> bool {
ReadLock Lock(mServer.GetClientMutex());
if (!ClientPtr.expired()) {
auto c = ClientPtr.lock();
Packet += c->GetName() + ",";
@ -576,6 +589,7 @@ int TNetwork::OpenID() {
do {
found = true;
mServer.ForEachClient([&](const std::weak_ptr<TClient>& ClientPtr) -> bool {
ReadLock Lock(mServer.GetClientMutex());
if (!ClientPtr.expired()) {
auto c = ClientPtr.lock();
if (c->GetID() == ID) {
@ -794,8 +808,13 @@ bool TNetwork::SyncClient(const std::weak_ptr<TClient>& c) {
bool Return = false;
bool res = true;
mServer.ForEachClient([&](const std::weak_ptr<TClient>& ClientPtr) -> bool {
std::shared_ptr<TClient> client;
{
ReadLock Lock(mServer.GetClientMutex());
if (!ClientPtr.expired()) {
auto client = ClientPtr.lock();
client = ClientPtr.lock();
} else return true;
}
TClient::TSetOfVehicleData VehicleData;
{ // Vehicle Data Lock Scope
auto LockedData = client->GetAllCars();
@ -812,7 +831,7 @@ bool TNetwork::SyncClient(const std::weak_ptr<TClient>& c) {
std::this_thread::sleep_for(std::chrono::seconds(2));
}
}
}
return true;
});
LockedClient->SetIsSyncing(false);
@ -830,8 +849,13 @@ void TNetwork::SendToAll(TClient* c, const std::string& Data, bool Self, bool Re
char C = Data.at(0);
bool ret = true;
mServer.ForEachClient([&](std::weak_ptr<TClient> ClientPtr) -> bool {
std::shared_ptr<TClient> Client;
{
ReadLock Lock(mServer.GetClientMutex());
if (!ClientPtr.expired()) {
auto Client = ClientPtr.lock();
Client = ClientPtr.lock();
}else return true;
}
if (Self || Client.get() != c) {
if (Client->IsSynced() || Client->IsSyncing()) {
if (Rel || C == 'W' || C == 'Y' || C == 'V' || C == 'E') {
@ -845,7 +869,6 @@ void TNetwork::SendToAll(TClient* c, const std::string& Data, bool Self, bool Re
}
}
}
}
return true;
});
if (!ret) {

View File

@ -31,8 +31,13 @@ void TPPSMonitor::operator()() {
continue;
}
mServer.ForEachClient([&](const std::weak_ptr<TClient>& ClientPtr) -> bool {
std::shared_ptr<TClient> c;
{
ReadLock Lock(mServer.GetClientMutex());
if (!ClientPtr.expired()) {
auto c = ClientPtr.lock();
c = ClientPtr.lock();
} else return true;
}
if (c->GetCarCount() > 0) {
C++;
V += c->GetCarCount();
@ -45,7 +50,7 @@ void TPPSMonitor::operator()() {
debug("client " + std::string("(") + std::to_string(c->GetID()) + ")" + c->GetName() + " timing out: " + std::to_string(c->SecondsSinceLastPing()) + ", pps: " + Application::PPS());
TimedOutClients.push_back(c);
}
}
return true;
});
for (auto& ClientToKick : TimedOutClients) {

View File

@ -48,7 +48,6 @@ std::weak_ptr<TClient> TServer::InsertNewClient() {
}
void TServer::ForEachClient(const std::function<bool(std::weak_ptr<TClient>)>& Fn) {
ReadLock Lock(mClientsMutex);
for (auto& Client : mClients) {
if (!Fn(Client)) {
break;