source: trunk/Packages/Common/UPool.pas

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