瀏覽代碼

Fix for Mantis #30453: add Delphi compatible TThreadList<>

git-svn-id: trunk@34278 -
svenbarth 9 年之前
父節點
當前提交
7678f5ecf0
共有 1 個文件被更改,包括 87 次插入2 次删除
  1. 87 2
      packages/rtl-generics/src/generics.collections.pas

+ 87 - 2
packages/rtl-generics/src/generics.collections.pas

@@ -32,7 +32,7 @@ unit Generics.Collections;
 interface
 
 uses
-    Classes, SysUtils, Generics.MemoryExpanders, Generics.Defaults, 
+    Classes, SysUtils, Generics.MemoryExpanders, Generics.Defaults,
     Generics.Helpers, Generics.Strings;
 
 { FPC BUGS related to Generics.* (54 bugs, 19 fixed)
@@ -40,7 +40,7 @@ uses
   FIXED REGRESSION: 26480, 26482
 
   CRITICAL: 24848(!!!), 24872(!), 25607(!), 26030, 25917, 25918, 25620, 24283, 24254, 24287 (Related to? 24872)
-  IMPORTANT: 23862(!), 24097, 24285, 24286 (Similar to? 24285), 24098, 24609 (RTL inconsistency), 24534, 
+  IMPORTANT: 23862(!), 24097, 24285, 24286 (Similar to? 24285), 24098, 24609 (RTL inconsistency), 24534,
              25606, 25614, 26177, 26195
   OTHER: 26484, 24073, 24463, 25593, 25596, 25597, 25602, 26181 (or MYBAD?)
   CLOSED BUT IMO STILL TO FIX: 25601(!), 25594
@@ -230,6 +230,25 @@ type
     property Items[Index: SizeInt]: T read GetItem write SetItem; default;
   end;
 
+  TThreadList<T> = class
+  private
+    FList: TList<T>;
+    FDuplicates: TDuplicates;
+    FLock: TRTLCriticalSection;
+  public
+    constructor Create;
+    destructor Destroy; override;
+
+    procedure Add(constref AValue: T);
+    procedure Remove(constref AValue: T);
+    procedure Clear;
+
+    function LockList: TList<T>;
+    procedure UnlockList; inline;
+
+    property Duplicates: TDuplicates read FDuplicates write FDuplicates;
+  end;
+
   TQueue<T> = class(TCustomList<T>)
   protected
     // bug #24287 - workaround for generics type name conflict (Identifier not found)
@@ -980,6 +999,72 @@ begin
   Result := TArrayHelperBugHack.BinarySearch(FItems, AItem, AIndex, AComparer);
 end;
 
+{ TThreadList<T> }
+
+constructor TThreadList<T>.Create;
+begin
+  inherited Create;
+  FDuplicates:=dupIgnore;
+  InitCriticalSection(FLock);
+  FList := TList<T>.Create;
+end;
+
+destructor TThreadList<T>.Destroy;
+begin
+  LockList;
+  try
+    FList.Free;
+    inherited Destroy;
+  finally
+    UnlockList;
+    DoneCriticalSection(FLock);
+  end;
+end;
+
+procedure TThreadList<T>.Add(constref AValue: T);
+begin
+  LockList;
+  try
+    if (Duplicates = dupAccept) or (FList.IndexOf(AValue) = -1) then
+      FList.Add(AValue)
+    else if Duplicates = dupError then
+      raise EArgumentException.CreateRes(@SDuplicatesNotAllowed);
+  finally
+    UnlockList;
+  end;
+end;
+
+procedure TThreadList<T>.Remove(constref AValue: T);
+begin
+  LockList;
+  try
+    FList.Remove(AValue);
+  finally
+    UnlockList;
+  end;
+end;
+
+procedure TThreadList<T>.Clear;
+begin
+  LockList;
+  try
+    FList.Clear;
+  finally
+    UnlockList;
+  end;
+end;
+
+function TThreadList<T>.LockList: TList<T>;
+begin
+  Result:=FList;
+  System.EnterCriticalSection(FLock);
+end;
+
+procedure TThreadList<T>.UnlockList;
+begin
+  System.LeaveCriticalSection(FLock);
+end;
+
 { TQueue<T>.TEnumerator }
 
 constructor TQueue<T>.TEnumerator.Create(AQueue: TQueue<T>);