source: trunk/Packages/Common/Pool.pas

Last change on this file was 30, checked in by chronos, 6 months ago
  • Modified: Updated Common package.
File size: 4.1 KB
Line 
1unit Pool;
2
3interface
4
5uses
6 Classes, SysUtils, syncobjs, Generics.Collections, Threading;
7
8type
9 TPoolItemClass = class of TObject;
10
11 { TPool }
12
13 TPool = class
14 private
15 FReleaseEvent: TEvent;
16 function GetTotalCount: Integer;
17 function GetUsedCount: Integer; virtual;
18 procedure SetTotalCount(const AValue: Integer);
19 protected
20 function NewItemObject: TObject; virtual;
21 public
22 Items: TObjectList<TObject>;
23 FreeItems: TObjectList<TObject>;
24 function Acquire: TObject; virtual;
25 procedure Release(Item: TObject); virtual;
26 constructor Create; virtual;
27 destructor Destroy; override;
28 property TotalCount: Integer read GetTotalCount write SetTotalCount;
29 property UsedCount: Integer read GetUsedCount;
30 end;
31
32 { TThreadedPool }
33
34 TThreadedPool = class(TPool)
35 private
36 procedure SetTotalCount(const AValue: Integer);
37 function GetUsedCount: Integer; override;
38 public
39 Lock: TCriticalSection;
40 function Acquire: TObject; override;
41 procedure Release(Item: TObject); override;
42 constructor Create; override;
43 destructor Destroy; override;
44 end;
45
46resourcestring
47 SObjectPoolEmpty = 'Object pool is empty';
48 SReleaseError = 'Unknown object for release from pool';
49
50
51implementation
52
53{ TThreadedPool }
54
55procedure TThreadedPool.SetTotalCount(const AValue: Integer);
56begin
57 try
58 Lock.Acquire;
59 inherited;
60 finally
61 Lock.Release;
62 end;
63end;
64
65function TThreadedPool.GetUsedCount: Integer;
66begin
67 try
68 Lock.Acquire;
69 Result := inherited;
70 finally
71 Lock.Release;
72 end;
73end;
74
75function TThreadedPool.Acquire: TObject;
76begin
77 try
78 Lock.Acquire;
79 if Items.Count = 0 then
80 raise Exception.Create(SObjectPoolEmpty);
81 while FreeItems.Count = 0 do begin
82 try
83 Lock.Release;
84 //FReleaseEvent.WaitFor(1);
85 Sleep(1);
86 finally
87 Lock.Acquire;
88 end;
89 end;
90 Result := inherited;
91 finally
92 Lock.Release;
93 end;
94end;
95
96procedure TThreadedPool.Release(Item: TObject);
97begin
98 try
99 Lock.Acquire;
100 inherited;
101 finally
102 Lock.Release;
103 end;
104end;
105
106constructor TThreadedPool.Create;
107begin
108 inherited;
109 Lock := TCriticalSection.Create;
110end;
111
112destructor TThreadedPool.Destroy;
113begin
114 TotalCount := 0;
115 FreeAndNil(Lock);
116 inherited;
117end;
118
119{ TPool }
120
121function TPool.NewItemObject: TObject;
122begin
123 // Overload this method in descendand classes for automatic creation propert item class
124 Result := TObject.Create;
125end;
126
127function TPool.GetUsedCount: Integer;
128begin
129 Result := Items.Count - FreeItems.Count;
130end;
131
132function TPool.GetTotalCount: Integer;
133begin
134 Result := Items.Count;
135end;
136
137procedure TPool.SetTotalCount(const AValue: Integer);
138var
139 I: Integer;
140begin
141 if AValue > Items.Count then begin
142 for I := Items.Count to AValue - 1 do begin
143 Items.Add(NewItemObject);
144 FreeItems.Add(Items.Last);
145 end;
146 end else
147 if AValue < Items.Count then begin
148 for I := Items.Count - 1 downto AValue do begin
149 while FreeItems.IndexOf(Items[I]) = -1 do
150 Sleep(1);
151 FreeItems.Delete(FreeItems.IndexOf(Items[I]));
152 Items.Delete(I);
153 end;
154 end;
155end;
156
157function TPool.Acquire: TObject;
158begin
159 while FreeItems.Count = 0 do begin
160 //FReleaseEvent.WaitFor(1);
161 Sleep(1);
162 end;
163 Result := FreeItems.Last;
164 FreeItems.Count := FreeItems.Count - 1;
165 //if not Assigned(Item) then
166 // raise Exception.Create(Format(S);
167end;
168
169procedure TPool.Release(Item: TObject);
170var
171 Index: Integer;
172begin
173 Index := Items.IndexOf(Item);
174 if Index = -1 then
175 raise Exception.Create(SReleaseError);
176
177 FreeItems.Add(Item);
178 //if FUsedCount < TotalCount then
179 // FReleaseEvent.SetEvent;
180end;
181
182constructor TPool.Create;
183begin
184 inherited;
185 Items := TObjectList<TObject>.Create;
186 FreeItems := TObjectList<TObject>.Create;
187 FreeItems.OwnsObjects := False;
188 FReleaseEvent := TEvent.Create(nil, False, False, '');
189end;
190
191destructor TPool.Destroy;
192begin
193 TotalCount := 0;
194 FreeAndNil(FReleaseEvent);
195 FreeAndNil(FreeItems);
196 FreeAndNil(Items);
197 inherited;
198end;
199
200end.
Note: See TracBrowser for help on using the repository browser.