source: branches/2.19.1/Library/Semaphores.pas@ 265

Last change on this file since 265 was 17, checked in by RBRi, 19 years ago

+ Library

  • Property svn:eol-style set to native
File size: 6.4 KB
Line 
1Unit Semaphores;
2
3Interface
4
5Uses
6{$ifdef os2}
7 BseDos;
8{$else}
9 Windows;
10{$endif}
11
12Type
13{$ifdef win32}
14 Hev = THandle;
15 HMtx = THandle;
16{$endif}
17
18 TEventSemaphore = class
19 protected
20 _Handle: HEv;
21 _Name: string;
22 _AlreadyExisted: boolean;
23 public
24 Constructor Create;
25 Constructor CreateNamed( const Name: string );
26 Destructor Destroy; override;
27
28 procedure Post;
29 procedure Reset;
30 function IsPosted: boolean;
31 procedure Wait;
32
33 property Handle: HEv read _Handle;
34 end;
35
36 TWaitType = ( wtAny, wtAll );
37
38{$ifdef os2}
39 TSemaphoreArray = Array[ 0..0 ] of SEMRECORD;
40 TPSemaphoreArray = ^TSemaphoreArray;
41{$else}
42 TSemaphoreArray = Array[ 0..0 ] of TEventSemaphore;
43 TPSemaphoreArray = ^TSemaphoreArray;
44{$endif}
45
46 TMultiWaitSemaphore = class
47 protected
48 _WaitType: TWaitType;
49{$ifdef os2}
50 _Handle: HMux;
51 _PSemaphoreArray: TPSemaphoreArray;
52{$else}
53 _PSemaphoreHandleArray: PWOHandleArray;
54 _PSemaphoreArray: TPSemaphoreArray;
55{$endif}
56 _SemaphoreCount: longint;
57 public
58 Constructor Create( WaitType: TWaitType;
59 Semaphores: array of TEventSemaphore );
60 Destructor Destroy; Override;
61
62 // Returns which event semaphore was posted
63 Function Wait: TEventSemaphore;
64 end;
65
66 TMutex = class
67 protected
68 _Handle: HMtx;
69 public
70 constructor Create;
71 constructor CreateNamed( const Name: string );
72 destructor Destroy; override;
73
74 procedure Get;
75 procedure Release;
76 end;
77
78Implementation
79
80// Turn off range checking since we are playing with dynamic arrays
81{$R-}
82
83Constructor TEventSemaphore.Create;
84begin
85{$ifdef os2}
86 DosCreateEventSem( nil, // unnamed
87 _Handle,
88 0, // not shared
89 false );
90{$else}
91 _Handle:= CreateEvent( nil, // no security
92 true, // manual reset please
93 false, // initially cleared
94 nil ); // no name
95{$endif}
96end;
97
98Constructor TEventSemaphore.CreateNamed( const Name: string );
99{$ifdef os2}
100var
101 CName: Cstring;
102{$endif}
103begin
104 _Name := Name;
105{$ifdef os2}
106 CName := Name;
107 DosCreateEventSem( CName, // unnamed
108 _Handle,
109 DC_SEM_SHARED, // shared
110 false );
111{$else}
112 _Handle:= CreateEvent( nil, // no security
113 true, // manual reset please
114 false, // initially cleared
115 PChar( name ) ); // no name
116{$endif}
117end;
118
119Destructor TEventSemaphore.Destroy;
120begin
121{$ifdef os2}
122 DosCloseEventSem( _Handle );
123{$else}
124 CloseHandle( _Handle );
125{$endif}
126end;
127
128procedure TEventSemaphore.Post;
129begin
130{$ifdef os2}
131 DosPostEventSem( _Handle );
132{$else}
133 SetEvent( _Handle );
134{$endif}
135end;
136
137procedure TEventSemaphore.Reset;
138{$ifdef os2}
139var
140 PostCount: Longword;
141{$endif}
142begin
143{$ifdef os2}
144 DosResetEventSem( _Handle, PostCount );
145{$else}
146 ResetEvent( _Handle);
147{$endif}
148end;
149
150function TEventSemaphore.IsPosted: boolean;
151{$ifdef os2}
152var
153 PostCount: Longword;
154{$endif}
155begin
156{$ifdef os2}
157 DosQueryEventSem( _Handle, PostCount );
158 Result:= ( PostCount > 0 );
159{$else}
160 if WaitForSingleObject( _Handle,
161 0 ) // return immediately...
162 = WAIT_OBJECT_0 then
163 Result:= true
164 else
165 Result:= false;
166 // ? doesn't seem to be possible...
167{$endif}
168end;
169
170procedure TEventSemaphore.Wait;
171begin
172{$ifdef os2}
173 DosWaitEventSem( Handle, SEM_INDEFINITE_WAIT );
174{$else}
175 WaitForSingleObject( _Handle,
176 INFINITE );
177{$endif}
178end;
179
180Constructor TMultiWaitSemaphore.Create( WaitType: TWaitType;
181 Semaphores: array of TEventSemaphore );
182var
183 i: longint;
184 SemIndex: longint;
185
186{$ifdef os2}
187 flAttr: Longword;
188{$endif}
189
190begin
191 _WaitType:= WaitType;
192
193 _SemaphoreCount:= High( Semaphores ) - Low( Semaphores ) + 1;
194{$ifdef os2}
195 GetMem( _PSemaphoreArray, Sizeof( SEMRECORD ) * _SemaphoreCount );
196{$else}
197 GetMem( _PSemaphoreHandleArray, Sizeof( THandle ) * _SemaphoreCount );
198 GetMem( _PSemaphoreArray, Sizeof( TEventSemaphore ) * _SemaphoreCount );
199{$endif}
200
201 for i:= 0 to _SemaphoreCount - 1 do
202 begin
203 SemIndex:= i + Low( Semaphores );
204{$ifdef os2}
205 _PSemaphoreArray^[ i ].hSemCur:= Semaphores[ SemIndex ].Handle;
206 _PSemaphoreArray^[ i ].ulUser:= longword( Semaphores[ SemIndex ] );
207{$else}
208 _PSemaphoreHandleArray^[ i ]:= Semaphores[ SemIndex ].Handle;
209 _PSemaphoreArray^[ i ]:= Semaphores[ SemIndex ];
210{$endif}
211 end;
212
213{$ifdef os2}
214 case _WaitType of
215 wtAll:
216 flAttr:= DCMW_WAIT_ALL;
217 wtAny:
218 flAttr:= DCMW_WAIT_ANY;
219 end;
220
221 DosCreateMuxWaitSem( nil,
222 _Handle,
223 _SemaphoreCount,
224 _PSemaphoreArray^,
225 flAttr );
226{$endif}
227// nothing to do for Win32...
228
229end;
230
231Destructor TMultiWaitSemaphore.Destroy;
232begin
233{$ifdef os2}
234 DosCloseMuxWaitSem( _Handle );
235 FreeMem( _PSemaphoreArray, Sizeof( SEMRECORD ) * _SemaphoreCount );
236{$else}
237 FreeMem( _PSemaphoreArray, Sizeof( THandle ) * _SemaphoreCount );
238{$endif}
239end;
240
241Function TMultiWaitSemaphore.Wait: TEventSemaphore;
242var
243 WhichSem: LongWord;
244{$ifdef win32}
245 WaitAll: BOOL;
246{$endif}
247begin
248{$ifdef os2}
249 DosWaitMuxWaitSem( _Handle, SEM_INDEFINITE_WAIT, WhichSem );
250 Result:= TEventSemaphore( WhichSem );
251{$else}
252 WaitAll:= ( _WaitType = wtAll );
253
254 WhichSem:=
255 WaitForMultipleObjects( _SemaphoreCount,
256 _PSemaphoreHandleArray,
257 WaitAll,
258 INFINITE )
259 - WAIT_OBJECT_0;
260 Result:= _PSemaphoreArray^[ WhichSem ];
261{$endif}
262
263end;
264
265constructor TMutex.Create;
266begin
267{$ifdef os2}
268 DosCreateMutexSem( nil, _Handle, 0, false );
269{$else}
270 _Handle:= CreateMutex( nil, false, nil );
271{$endif}
272end;
273
274constructor TMutex.CreateNamed( const Name: string );
275{$ifdef os2}
276var
277 CName: Cstring;
278{$endif}
279begin
280{$ifdef os2}
281 CName := Name;
282 DosCreateMutexSem( CName, _Handle, 0, false );
283{$else}
284 _Handle:= CreateMutex( nil, false, PChar( Name ) );
285{$endif}
286end;
287
288destructor TMutex.Destroy;
289begin
290{$ifdef os2}
291 DosCloseMutexSem( _Handle );
292{$else}
293 CloseHandle( _Handle );
294{$endif}
295 inherited Destroy;
296end;
297
298procedure TMutex.Get;
299begin
300{$ifdef os2}
301 DosRequestMutexSem( _Handle, SEM_INDEFINITE_WAIT );
302{$else}
303 WaitForSingleObject( _Handle, INFINITE );
304{$endif}
305end;
306
307procedure TMutex.Release;
308begin
309{$ifdef os2}
310 DosReleaseMutexSem( _Handle );
311{$else}
312 ReleaseMutex( _Handle );
313{$endif}
314end;
315
316Initialization
317End.
318
Note: See TracBrowser for help on using the repository browser.