Browse Source

For connections list TThreadList changed to safe TFPHashList.

Yuri Serebrennikov 1 year ago
parent
commit
276618563c
1 changed files with 83 additions and 21 deletions
  1. 83 21
      packages/fcl-web/src/websocket/fpcustwsserver.pp

+ 83 - 21
packages/fcl-web/src/websocket/fpcustwsserver.pp

@@ -27,7 +27,8 @@ uses
   System.Classes, System.SysUtils, System.Net.Ssockets, Fcl.ThreadPool, FpWeb.WebSocket.Protocol;
 {$ELSE FPC_DOTTEDUNITS}
 uses
-  Classes, SysUtils, ssockets, fpthreadpool, fpwebsocket;
+  Classes, SysUtils, Contnrs,
+  ssockets, fpthreadpool, fpwebsocket;
 {$ENDIF FPC_DOTTEDUNITS}
 
 Const
@@ -49,7 +50,18 @@ Type
 
   { TWSConnectionList }
 
-  TWSConnectionList = Class(TThreadList)
+  TWSConnectionList = class
+  private
+    FList: TFPHashList;
+    FLock: TRTLCriticalSection;
+  public
+    constructor Create;
+    destructor Destroy; override;
+    procedure Add(Item: TWSConnection);
+    procedure Clear;
+    function LockList: TFPHashList;
+    procedure Remove(Item: TWSConnection);
+    procedure UnlockList;
     Function ForEach(aIterator : TConnectionIterator) : Boolean;
     Function FindConnectionById(const aID : String) : TWSConnection;
   end;
@@ -275,11 +287,70 @@ implementation
 
 { TWSConnectionList }
 
+constructor TWSConnectionList.Create;
+begin
+  FList := TFPHashList.Create;
+  InitCriticalSection(FLock);
+end;
+
+destructor TWSConnectionList.Destroy;
+begin
+  LockList;
+  try
+    FList.Free;
+    inherited Destroy;
+  finally
+    UnlockList;
+    DoneCriticalSection(FLock);
+  end;
+end;
+
+procedure TWSConnectionList.Add(Item: TWSConnection);
+begin
+  LockList;
+  try
+    if FList.IndexOf(Item) = -1 then
+      FList.Add(Item.ConnectionID, Item);
+  finally
+    UnlockList;
+  end;
+end;
+
+procedure TWSConnectionList.Clear;
+begin
+  Locklist;
+  try
+    FList.Clear;
+  finally
+    UnLockList;
+  end;
+end;
+
+function TWSConnectionList.LockList: TFPHashList;
+begin
+  Result:=FList;
+  System.EnterCriticalSection(FLock);
+end;
+
+procedure TWSConnectionList.Remove(Item: TWSConnection);
+begin
+  LockList;
+  try
+    FList.Remove(Item);
+  finally
+    UnlockList;
+  end;
+end;
+
+procedure TWSConnectionList.UnlockList;
+begin
+  LeaveCriticalSection(FLock);
+end;
+
 function TWSConnectionList.ForEach(aIterator: TConnectionIterator): Boolean;
-Var
-  L : TList;
+var
+  L : TFPHashList;
   I : Integer;
-
 begin
   Result:=True;
   L:=LockList;
@@ -297,21 +368,12 @@ end;
 
 function TWSConnectionList.FindConnectionById(const aID: String): TWSConnection;
 Var
-  L : TList;
-  I : Integer;
-
+  L: TFPHashList;
 begin
   Result:=Nil;
   L:=LockList;
   try
-    I:=0;
-    While (Result=Nil) and (I<L.Count) do
-      begin
-      Result:=TWSServerConnection(L[I]);
-      if Result.ConnectionID<>aID then
-        Result:=Nil;
-      Inc(I);
-      end;
+    Result := TWSConnection(L.Find(aId));
   finally
     UnlockList;
   end;
@@ -422,7 +484,7 @@ procedure TCustomWSServer.SendDataTo(AData: TBytes; aSelector: TWSSendToFilter);
 
 var
   Connection: TWSServerConnection;
-  L : TList;
+  L : TFPHashList;
   I : integer;
 
 begin
@@ -441,7 +503,7 @@ end;
 
 procedure TCustomWSServer.Foreach(aIterator: TConnectionIterator);
 Var
-  L : TList;
+  L : TFPHashList;
   aContinue : Boolean;
   I : Integer;
 begin
@@ -471,7 +533,7 @@ procedure TCustomWSServer.SendFrameTo(aFrame: TWSFrame; aSelector: TWSSendToFilt
 
 var
   Connection: TWSServerConnection;
-  L : TList;
+  L : TFPHashList;
   I : integer;
 
 begin
@@ -501,7 +563,7 @@ procedure TCustomWSServer.SendMessageTo(const AMessage: string;
 
 var
   Connection: TWSServerConnection;
-  L : TList;
+  L : TFPHashList;
   I : integer;
 
 begin
@@ -589,7 +651,7 @@ end;
 function TCustomWSServer.GetActiveConnectionCount: Integer;
 
 Var
-  L : TList;
+  L : TFPHashList;
 begin
   L:=Connections.LockList;
   try