1 | unit UPool;
|
---|
2 |
|
---|
3 | {$mode Delphi}{$H+}
|
---|
4 |
|
---|
5 | interface
|
---|
6 |
|
---|
7 | uses
|
---|
8 | Classes, SysUtils, syncobjs, fgl, UThreading;
|
---|
9 |
|
---|
10 | type
|
---|
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 |
|
---|
48 | resourcestring
|
---|
49 | SObjectPoolEmpty = 'Object pool is empty';
|
---|
50 | SReleaseError = 'Unknown object for release from pool';
|
---|
51 |
|
---|
52 |
|
---|
53 | implementation
|
---|
54 |
|
---|
55 | { TThreadedPool }
|
---|
56 |
|
---|
57 | procedure TThreadedPool.SetTotalCount(const AValue: Integer);
|
---|
58 | begin
|
---|
59 | try
|
---|
60 | Lock.Acquire;
|
---|
61 | inherited SetTotalCount(AValue);
|
---|
62 | finally
|
---|
63 | Lock.Release;
|
---|
64 | end;
|
---|
65 | end;
|
---|
66 |
|
---|
67 | function TThreadedPool.GetUsedCount: Integer;
|
---|
68 | begin
|
---|
69 | try
|
---|
70 | Lock.Acquire;
|
---|
71 | Result := inherited GetUsedCount;
|
---|
72 | finally
|
---|
73 | Lock.Release;
|
---|
74 | end;
|
---|
75 | end;
|
---|
76 |
|
---|
77 | function TThreadedPool.Acquire: TObject;
|
---|
78 | begin
|
---|
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;
|
---|
96 | end;
|
---|
97 |
|
---|
98 | procedure TThreadedPool.Release(Item: TObject);
|
---|
99 | begin
|
---|
100 | try
|
---|
101 | Lock.Acquire;
|
---|
102 | inherited Release(Item);
|
---|
103 | finally
|
---|
104 | Lock.Release;
|
---|
105 | end;
|
---|
106 | end;
|
---|
107 |
|
---|
108 | constructor TThreadedPool.Create;
|
---|
109 | begin
|
---|
110 | inherited Create;
|
---|
111 | Lock := TCriticalSection.Create;
|
---|
112 | end;
|
---|
113 |
|
---|
114 | destructor TThreadedPool.Destroy;
|
---|
115 | begin
|
---|
116 | TotalCount := 0;
|
---|
117 | Lock.Free;
|
---|
118 | inherited Destroy;
|
---|
119 | end;
|
---|
120 |
|
---|
121 | { TPool }
|
---|
122 |
|
---|
123 | function TPool.NewItemObject: TObject;
|
---|
124 | begin
|
---|
125 | // Overload this method in descendand classes for automatic creation propert item class
|
---|
126 | Result := TObject.Create;
|
---|
127 | end;
|
---|
128 |
|
---|
129 | function TPool.GetUsedCount: Integer;
|
---|
130 | begin
|
---|
131 | Result := Items.Count - FreeItems.Count;
|
---|
132 | end;
|
---|
133 |
|
---|
134 | function TPool.GetTotalCount: Integer;
|
---|
135 | begin
|
---|
136 | Result := Items.Count;
|
---|
137 | end;
|
---|
138 |
|
---|
139 | procedure TPool.SetTotalCount(const AValue: Integer);
|
---|
140 | var
|
---|
141 | I: Integer;
|
---|
142 | begin
|
---|
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;
|
---|
157 | end;
|
---|
158 |
|
---|
159 | function TPool.Acquire: TObject;
|
---|
160 | begin
|
---|
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);
|
---|
169 | end;
|
---|
170 |
|
---|
171 | procedure TPool.Release(Item: TObject);
|
---|
172 | var
|
---|
173 | Index: Integer;
|
---|
174 | begin
|
---|
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;
|
---|
182 | end;
|
---|
183 |
|
---|
184 | constructor TPool.Create;
|
---|
185 | begin
|
---|
186 | inherited;
|
---|
187 | Items := TFPGObjectList<TObject>.Create;
|
---|
188 | FreeItems := TFPGObjectList<TObject>.Create;
|
---|
189 | FreeItems.FreeObjects := False;
|
---|
190 | FReleaseEvent := TEvent.Create(nil, False, False, '');
|
---|
191 | end;
|
---|
192 |
|
---|
193 | destructor TPool.Destroy;
|
---|
194 | begin
|
---|
195 | TotalCount := 0;
|
---|
196 | FreeAndNil(FReleaseEvent);
|
---|
197 | FreeAndNil(FreeItems);
|
---|
198 | FreeAndNil(Items);
|
---|
199 | inherited;
|
---|
200 | end;
|
---|
201 |
|
---|
202 | end.
|
---|
203 |
|
---|