source: trunk/Library/Semaphores.pas@ 413

Last change on this file since 413 was 394, checked in by RBRi, 9 years ago

+ copyright

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