source: branches/DirectWeb/UPool.pas

Last change on this file was 89, checked in by george, 15 years ago
  • Opraveno: Chybné vytváření pojmenovaných objektů TEvent.
  • Opraveno: Chybné přidělování a uvolňování zásobníků vláken a databázových spojení.
  • Opraveno: Chybná inicializace parametrů databázových spojení.
File size: 2.9 KB
Line 
1unit UPool;
2
3{$mode Delphi}{$H+}
4
5interface
6
7uses
8 Classes, SysUtils, Contnrs, syncobjs;
9
10type
11
12 { TThreadedPoolItem }
13
14 TThreadedPoolItem = class
15 Used: Boolean;
16 Item: TObject;
17 constructor Create;
18 destructor Destroy; override;
19 end;
20
21 { TThreadedPool }
22
23 TThreadedPool = class(TObjectList)
24 private
25 Lock: TCriticalSection;
26 ReleaseEvent: TEvent;
27 FTotalCount: Integer;
28 function IndexOfObjectItem(Item: TObject): Integer;
29 procedure SetTotalCount(const AValue: Integer);
30 public
31 UsedCount: Integer;
32 function GetUnused: TThreadedPoolItem;
33 function Acquire: TObject;
34 procedure Release(Item: TObject);
35 constructor Create;
36 destructor Destroy; override;
37 property TotalCount: Integer read FTotalCount write SetTotalCount;
38 end;
39
40implementation
41
42{ TThreadedPool }
43
44function TThreadedPool.GetUnused: TThreadedPoolItem;
45var
46 I: Integer;
47begin
48 I := 0;
49 while (I < Count) and (TThreadedPoolItem(Items[I]).Used) do
50 Inc(I);
51 if I < Count then Result := TThreadedPoolItem(Items[I])
52 else Result := nil;
53end;
54
55function TThreadedPool.IndexOfObjectItem(Item: TObject): Integer;
56var
57 I: Integer;
58begin
59 I := 0;
60 while (I < Count) and (TThreadedPoolItem(Items[I]).Item <> Item) do
61 Inc(I);
62 if I < Count then Result := I
63 else Result := -1;
64end;
65
66procedure TThreadedPool.SetTotalCount(const AValue: Integer);
67var
68 I: Integer;
69begin
70 if AValue > FTotalCount then begin
71 for I := FTotalCount to AValue - 1 do
72 Add(TThreadedPoolItem.Create);
73 end else
74 if AValue < FTotalCount then begin
75 for I := AValue to FTotalCount - 1 do
76 TThreadedPoolItem(Items[I]).Destroy;
77 end;
78 FTotalCount := AValue;
79end;
80
81function TThreadedPool.Acquire: TObject;
82var
83 Item: TThreadedPoolItem;
84begin
85 try
86 Lock.Acquire;
87 while UsedCount = TotalCount do begin
88 Lock.Release;
89 ReleaseEvent.WaitFor(1000);
90 Lock.Acquire;
91 end;
92 Item := GetUnused;
93 Item.Used := True;
94 Result := Item.Item;
95 Inc(UsedCount);
96 finally
97 Lock.Release;
98 end;
99end;
100
101procedure TThreadedPool.Release(Item: TObject);
102var
103 Index: Integer;
104begin
105 try
106 Lock.Acquire;
107 Index := IndexOfObjectItem(Item);
108 with TThreadedPoolItem(Items[Index]) do begin
109 Used := False;
110 end;
111 Dec(UsedCount);
112 if UsedCount < TotalCount then ReleaseEvent.SetEvent;
113 finally
114 Lock.Release;
115 end;
116end;
117
118constructor TThreadedPool.Create;
119begin
120 inherited;
121 Lock := TCriticalSection.Create;
122 ReleaseEvent := TEvent.Create(nil, False, False, '');
123end;
124
125destructor TThreadedPool.Destroy;
126begin
127 ReleaseEvent.Destroy;
128 Lock.Destroy;
129 inherited Destroy;
130end;
131
132{ TThreadedPoolItem }
133
134constructor TThreadedPoolItem.Create;
135begin
136 Item := nil;
137end;
138
139destructor TThreadedPoolItem.Destroy;
140begin
141 if Assigned(Item) then Item.Destroy;
142 inherited Destroy;
143end;
144
145end.
146
Note: See TracBrowser for help on using the repository browser.