forked from SoDOff-Project/sodoff-mmo
use ReaderWriterLockSlim for lock Room.clients
This commit is contained in:
parent
d0c1839b11
commit
a4039451f3
@ -85,7 +85,8 @@ public class GauntletRoom : Room {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public bool ProcessResult(Client client, string resultA, string resultB) {
|
public bool ProcessResult(Client client, string resultA, string resultB) {
|
||||||
lock (base.roomLock) {
|
base.roomLock.EnterWriteLock();
|
||||||
|
try {
|
||||||
players[client].resultA = resultA;
|
players[client].resultA = resultA;
|
||||||
players[client].resultB = resultB;
|
players[client].resultB = resultB;
|
||||||
|
|
||||||
@ -112,6 +113,8 @@ public class GauntletRoom : Room {
|
|||||||
|
|
||||||
Send(packet);
|
Send(packet);
|
||||||
return true;
|
return true;
|
||||||
|
} finally {
|
||||||
|
base.roomLock.ExitWriteLock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Threading;
|
||||||
using sodoffmmo.Data;
|
using sodoffmmo.Data;
|
||||||
|
|
||||||
namespace sodoffmmo.Core;
|
namespace sodoffmmo.Core;
|
||||||
@ -8,7 +9,7 @@ public class Room {
|
|||||||
protected static Dictionary<string, Room> rooms = new();
|
protected static Dictionary<string, Room> rooms = new();
|
||||||
|
|
||||||
List<Client> clients = new();
|
List<Client> clients = new();
|
||||||
protected object roomLock = new object();
|
protected ReaderWriterLockSlim roomLock = new ReaderWriterLockSlim();
|
||||||
|
|
||||||
public int Id { get; private set; }
|
public int Id { get; private set; }
|
||||||
public string Name { get; private set; }
|
public string Name { get; private set; }
|
||||||
@ -38,40 +39,53 @@ public class Room {
|
|||||||
public IEnumerable<Client> Clients {
|
public IEnumerable<Client> Clients {
|
||||||
get {
|
get {
|
||||||
List<Client> list;
|
List<Client> list;
|
||||||
lock (roomLock) {
|
roomLock.EnterReadLock();
|
||||||
list = new List<Client>(clients);
|
try {
|
||||||
|
return new List<Client>(clients);
|
||||||
|
} finally {
|
||||||
|
roomLock.ExitReadLock();
|
||||||
}
|
}
|
||||||
return list;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddClient(Client client) {
|
public void AddClient(Client client) {
|
||||||
lock (roomLock) {
|
roomLock.EnterWriteLock();
|
||||||
|
try {
|
||||||
if (IsRemoved)
|
if (IsRemoved)
|
||||||
throw new Exception("Call AddClient on removed room");
|
throw new Exception("Call AddClient on removed room");
|
||||||
client.Send(RespondJoinRoom());
|
client.Send(RespondJoinRoom());
|
||||||
// NOTE: send RespondJoinRoom() and add client to clients as atomic operation
|
// NOTE: send RespondJoinRoom() and add client to clients as atomic operation
|
||||||
// to make sure to client get full list of players in room
|
// to make sure to client get full list of players in room
|
||||||
clients.Add(client);
|
clients.Add(client);
|
||||||
|
} finally {
|
||||||
|
roomLock.ExitWriteLock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveClient(Client client) {
|
public void RemoveClient(Client client) {
|
||||||
lock (roomLock) {
|
roomLock.EnterWriteLock();
|
||||||
|
try {
|
||||||
clients.Remove(client);
|
clients.Remove(client);
|
||||||
if (AutoRemove && ClientsCount == 0) {
|
if (AutoRemove && ClientsCount == 0) {
|
||||||
IsRemoved = true;
|
IsRemoved = true;
|
||||||
rooms.Remove(Name);
|
rooms.Remove(Name);
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
|
roomLock.ExitWriteLock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Send(NetworkPacket packet, Client? skip = null) {
|
public void Send(NetworkPacket packet, Client? skip = null) {
|
||||||
|
roomLock.EnterReadLock();
|
||||||
|
try {
|
||||||
foreach (var roomClient in clients) {
|
foreach (var roomClient in clients) {
|
||||||
if (roomClient != skip) {
|
if (roomClient != skip) {
|
||||||
roomClient.Send(packet);
|
roomClient.Send(packet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
|
roomLock.ExitReadLock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool Exists(string name) => rooms.ContainsKey(name);
|
public static bool Exists(string name) => rooms.ContainsKey(name);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user