source: trunk/Components/syncobjects.pas@ 15

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

+ components stuff

  • Property svn:eol-style set to native
File size: 11.6 KB
Line 
1Unit SyncObjects;
2
3/*********************************
4 Thread Synchronization Classes
5 for OS/2 and Win32
6
7 1998.12.07 by Jens Schiffler
8
9 Lochg„áchen 16
10 86152 Augsburg Germany
11
12 jensja@rz.fh-augsburg.de
13
14**********************************/
15
16/*
17 IN WIN95 MUSS CRIPPLED32 DEFINIERT SEIN
18 IN Win98 wohl nicht mehr???
19 */
20
21//{$define CRIPPLED32}
22
23Interface
24
25{$ifdef OS2}
26Uses
27 BseDos, BseErr, Os2Def;
28{$endif}
29{$ifdef WIN32}
30Uses
31 WinBase, WinNT, WIn32Add;
32{$endif}
33
34Const
35 INDEFINITE_WAIT= -1;
36 NO_WAIT= 0;
37
38 Procedure Delay(ms: LONGWORD);
39
40Type
41
42 TMutexSem= Class
43 {
44 Mutex Semaphor
45 }
46 Protected
47 FHandle: LONGWORD;
48 FName: CString;
49 Public
50 Constructor Create(shared: Boolean; name: CString; owned: Boolean);
51 Destructor Destroy; Override;
52 Function Request (TimeOut: LONGWORD): Boolean; virtual;
53 Function Release: Boolean; virtual;
54
55 Property Name: CString read FName;
56 End; { TMutexSem }
57
58 TCritSec= Class (TMutexSem)
59 {
60 Critical Section
61 }
62 {$ifdef WIN32}
63 FCRITICAL_SECTION: CRITICAL_SECTION;
64 {$endif}
65 Public
66 Constructor Create(name: CString);
67 Destructor Destroy; override;
68 Function Request (TimeOut: LONGWORD): Boolean; override;
69 Function Release: Boolean; override;
70 End;
71
72 TEventSem= Class
73 {
74 Event Semaphor (no count, only Set/Reset !)
75 }
76 Protected
77 FEvent: LONGWORD;
78 FName: CString;
79 FPostCount: LONGWORD;
80 Public
81 Constructor Create(shared: Boolean; name: CString; posted: Boolean);
82 Destructor Destroy; override;
83 Function Post: Boolean; virtual;
84 Function WaitFor(TimeOut: LONGWORD): Boolean; virtual;
85 Function Reset: Boolean; virtual;
86 Property LastPostCount: LONGWORD read FPostCount;
87 End;
88
89 TPeriodicTimer= Class(TEventSem)
90 {
91 Periodic Timer
92 }
93 Protected
94 FTimer: LONGWORD;
95 FInterval: LONGWORD; //millisekunden
96 Public
97 Constructor Create(shared: Boolean; name: CString; interval: LONGWORD);
98 Destructor Destroy; Override;
99 Function WaitFor(TimeOut: LONGWORD): Boolean; virtual;
100 Procedure Start; virtual;
101 Procedure Stop; virtual;
102 End;
103
104
105 Var
106 GlobalCritSec: TCritSec;
107 GlobalMutex: TMutexSem;
108
109Implementation
110
111/*--------------------
112 TMutexSem
113*/
114
115 Constructor TMutexSem.Create(shared: Boolean; name: CString; owned: Boolean);
116 {$ifdef OS2}
117 Var
118 rc: LONGWORD;
119 flAttr: LONGWORD;
120 Begin
121
122 If Shared Then flAttr:= BseDos.DC_SEM_SHARED
123 Else flAttr:= 0;
124
125 If Length(name) = 0 Then
126 Begin
127 rc:= BseDos.DosCreateMutexSem(
128 NIL,
129 FHandle,
130 flAttr,
131 owned
132 );
133 End
134 Else
135 Begin
136 FName:= name;
137 rc:= BseDos.DosCreateMutexSem(
138 name,
139 FHandle,
140 flAttr,
141 owned
142 );
143 End;
144
145 End;
146 {$endif}{OS2}
147 {$ifdef WIN32}
148 Begin
149 If Length(name) = 0 Then
150 Begin
151 FHandle:= WinBase.CreateMutex(
152 NIL, //lpSecurityAttributes
153 owned,
154 NIL //name
155 );
156 End
157 Else
158 Begin
159 FName:= name;
160 FHandle:= WinBase.CreateMutex(
161 NIL, //lpSecurityAttributes
162 owned,
163 name
164 );
165 End;
166// Result:= (FHandle <> 0);
167 End;
168 {$endif}{WIN32}
169
170 Destructor TMutexSem.Destroy;
171 {$ifdef OS2}
172 Begin
173 BseDos.DosCloseMutexSem(FHandle);
174 End;
175 {$endif}{OS2}
176 {$ifdef WIN32}
177 Begin
178 WinBase.CLoseHandle(FHandle);
179 End;
180 {$endif}{WIN32}
181
182 Function TMutexSem.Request (TimeOut: LONGWORD): Boolean;
183 {$ifdef OS2}
184 Var
185 rc: LONGWORD;
186 Begin
187 rc:= BseDos.DosRequesTMutexSem(FHandle, TimeOut);
188 Result:= (rc= BseErr.NO_ERROR);
189 End;
190 {$endif OS2}
191 {$ifdef WIN32}
192 Var
193 rc: LONGWORD;
194 Begin
195 rc:= WinBase.WaitForSingleObject(FHandle, TimeOut);
196 Result:= (rc= WAIT_OBJECT_0) OR (rc= WAIT_ABANDONED);
197 End;
198 {$endif WIN32}
199
200 Function TMutexSem.Release: Boolean;
201 {$ifdef OS2}
202 Var
203 rc: LONGWORD;
204 Begin
205 rc:= BseDos.DosReleaseMutexSem(FHandle);
206 Result:= (rc= BseErr.NO_ERROR);
207 End;
208 {$endif}{OS2}
209 {$ifdef WIN32}
210 Begin
211 Result:= WinBase.ReleaseMutex(FHandle);
212 End;
213 {$endif}{WIN32}
214
215/*----------------------
216 TCritSec
217*/
218 Constructor TCritSec.Create(name: CString);
219 {$ifdef OS2}
220 Begin
221 End;
222 {$endif}
223 {$ifdef WIN32}
224 Begin
225 WinBase.InitializeCriticalSection(FCRITICAL_SECTION);
226 End;
227 {$endif}
228
229 Destructor TCritSec.Destroy;
230 {$ifdef OS2}
231 Begin
232 End;
233 {$endif}
234 {$ifdef WIN32}
235 Begin
236 WinBase.DeleteCriticalSection(FCRITICAL_SECTION);
237 End;
238 {$endif}
239
240 Function TCritSec.Request (TimeOut: LONGWORD): Boolean;
241 {$ifdef OS2}
242 Begin
243 Result:= (BseDos.DosEnterCritSec= BseErr.NO_ERROR);
244 End;
245 {$endif}
246 {$ifdef WIN32}
247 Begin
248 WinBase.EnterCriticalSection(FCRITICAL_SECTION);
249 Result:= TRUE;
250 End;
251 {$endif}
252
253 Function TCritSec.Release: Boolean;
254 {$ifdef OS2}
255 Begin
256 Result:= (BseDos.DosExitCritSec= BseErr.NO_ERROR);
257 End;
258 {$endif}
259 {$ifdef WIN32}
260 Begin
261 WinBase.LeaveCriticalSection(FCRITICAL_SECTION);
262 Result:= TRUE;
263 End;
264 {$endif}
265
266/*
267 TEventSem
268*/
269 Constructor TEventSem.Create(shared: Boolean; name: CString; posted: Boolean);
270 {$ifdef OS2}
271 Var
272 rc,
273 flAttr: LONGWORD;
274 Begin
275
276 If shared Then
277 flAttr:= BseDos.DC_SEM_SHARED
278 Else
279 flAttr:= 0;
280
281 If Length(name) = 0 Then
282 Begin
283 rc:= BseDos.DosCreateEventSem(
284 NIL,
285 FEvent,
286 flAttr,
287 posted
288 );
289
290 End
291 Else
292 Begin
293 FName:= name;
294 rc:= BseDos.DosCreateEventSem(
295 name,
296 FEvent,
297 flAttr,
298 posted
299 );
300 End;
301
302// Result:= (rc= BseErr.NO_ERROR);
303 End;
304 {$endif}{OS2}
305 {$ifdef WIN32}
306 Begin
307 If Length(name) = 0 Then
308 Begin
309 FEvent:= WinBase.CreateEvent(
310 NIL, //SecurityAttributes
311 TRUE, //Manual Reset
312 posted,
313 NIL //Name
314 );
315 End
316 Else
317 Begin
318 FName:= name;
319 FEvent:= WinBase.CreateEvent(
320 NIL, //SecurityAttributes
321 TRUE, //Manual Reset
322 posted,
323 name
324 );
325 End;
326
327// Result:= (FHandle <> 0);
328 End;
329 {$endif}{WIN32}
330
331 Destructor TEventSem.Destroy;
332 {$ifdef OS2}
333 Begin
334 BseDos.DosCloseEventSem(FEvent);
335 End;
336 {$endif}{OS2}
337 {$ifdef WIN32}
338 Begin
339 WinBase.CloseHandle(FEvent);
340 End;
341 {$endif}{WIN32}
342
343 Function TEventSem.Post: Boolean;
344 {$ifdef OS2}
345 Begin
346 Result:= (BseDos.DosPostEventSem(FEvent) <> BseErr.ERROR_INVALID_HANDLE);
347 End;
348 {$endif}{OS2}
349 {$ifdef WIN32}
350 Begin
351 Result:= WinBase.SetEvent(FEvent);
352 End;
353 {$endif}{WIN32}
354
355 Function TEventSem.WaitFor(TimeOut: LONGWORD): Boolean;
356 {$ifdef OS2}
357 Begin
358 Result:= (BseDos.DosWaitEventSem(FEvent, TimeOut)= BseErr.NO_ERROR);
359 End;
360 {$endif}{OS2}
361 {$ifdef WIN32}
362 Var
363 rc: LONGWORD;
364 Begin
365 rc:= WinBase.WaitForSingleObject(FEvent, TimeOut);
366 Result:= (rc= WAIT_OBJECT_0) OR (rc= WAIT_ABANDONED);
367 End;
368 {$endif}{WIN32}
369
370 Function TEventSem.Reset: Boolean;
371 {$ifdef OS2}
372 Var
373 rc: LONGWORD;
374 Begin
375 rc:= BseDos.DosResetEventSem(FEvent, FPostCount);
376 Result:= (rc <> BseErr.ERROR_INVALID_HANDLE) AND (rc <> BseErr.ERROR_ALREADY_RESET);
377 End;
378 {$endif}{OS2}
379 {$ifdef WIN32}
380 Begin
381 Result:= WinBase.ResetEvent(FEvent);
382 End;
383 {$endif}{WIN32}
384
385/*
386 TPeriodicTimer.
387 NUR IN OS/2, WIN NT 4.0, WIN98
388 NICHT IN WIN95 -> Workaround mit Sleep
389*/
390 Constructor TPeriodicTimer.Create(shared: Boolean; name: CString; interval: LONGWORD);
391 {$ifdef OS2}
392 Begin
393 Inherited.Create(TRUE, name, FALSE); //TEventSem
394 BseDos.DosStartTimer(
395 interval,
396 FEvent,
397 FTimer
398 );
399 End;
400 {$endif}{OS2}
401 {$ifdef WIN32}
402 {$ifdef CRIPPLED32}
403 Begin
404 FInterval:= Interval;
405 End;
406 {$else}
407 Var
408 DUE_TIME: WinBase.FileTime;
409 Begin
410 If Length(name) = 0 Then
411 Begin
412 FTimer:= Win32Add.CreateWaitableTimer(
413 NIL, //Attribute
414 FALSE, //Manual Reset
415 NIL
416 );
417 End
418 Else
419 Begin
420 FName:= name;
421 FTimer:= Win32Add.CreateWaitableTimer(
422 NIL, //Attribute
423 FALSE, //Manual Reset
424 PChar(name)
425 );
426 End;
427
428 DUE_TIME.dwLowDateTime:= -1;
429 DUE_TIME.dwHighDateTime:= -1;
430
431 Win32Add.SetWaitableTimer(
432 FTimer,
433 @DUE_TIME, //NIL, //DueTime (64Bit)
434 Interval,
435 NIL, //Completion Routine
436 NIL, //Completion Routine Data
437 TRUE //Resume upon Power Suspend
438 );
439
440 End;
441 {$endif}{CRIPPLED32}
442 {$endif}{WIN32}
443
444 Destructor TPeriodicTimer.Destroy;
445 {$ifdef OS2}
446 Begin
447 Stop;
448 Inherited.Destroy;
449 End;
450 {$endif}{OS2}
451 {$ifdef WIN32}
452 {$ifdef CRIPPLED32}
453 Begin
454 End;
455 {$else}
456 Begin
457 Stop;
458 WinBase.CloseHandle(FTimer);
459 End;
460 {$endif}{CRIPPLED32}
461 {$endif}{WIN32}
462
463 Function TPeriodicTimer.WaitFor(TimeOut: LONGWORD): Boolean;
464 {$ifdef OS2}
465 Begin
466 Result:= Inherited.WaitFor(TimeOut);
467 If Result Then Result:= Inherited.Reset;
468 End;
469 {$endif}{OS2}
470 {$ifdef WIN32}
471 {$ifdef CRIPPLED32}
472 Begin
473 /*
474 Mieser Workaround!!!
475 */
476 WinBase.Sleep(FInterval);
477 Result:= TRUE;
478 End;
479 {$else}
480 Var
481 rc: LONGWORD;
482 Begin
483 rc:= WinBase.WaitForSingleObject(FTimer, TimeOut);
484 Result:= (rc= WAIT_OBJECT_0);// OR (rc= WAIT_ABANDONED); {only for mutex?}
485(*
486{ no reset necessary }
487 If Result Then
488 Begin
489
490 {rc:=} Win32Add.ResetWaitableTimer(FTimer);
491
492 End;
493*)
494 End;
495 {$endif}{CRIPPLED32}
496 {$endif}{WIN32}
497
498 Procedure TPeriodicTimer.Start;
499 {$ifdef OS2}
500 Begin
501 End;
502 {$endif}{OS2}
503 {$ifdef WIN32}
504 Begin
505 End;
506 {$endif}{WIN32}
507
508 Procedure TPeriodicTimer.Stop;
509 {$ifdef OS2}
510 Begin
511 BseDos.DosStopTimer(FTimer);
512 End;
513 {$endif}{OS2}
514 {$ifdef WIN32}
515 {$ifdef CRIPPLED32}
516 Begin
517 End;
518 {$else}
519 Begin
520 Win32Add.CancelWaitableTimer(FTimer);
521 End;
522 {$endif}{CRIPPLED32}
523 {$endif}{WIN32}
524
525 Procedure Delay(ms: LONGWORD);
526 Begin
527 {$ifdef OS2}
528 BseDos.DosSleep(ms);
529 {$endif}
530 {$ifdef WIN32}
531 WinBase.Sleep(ms);
532 {$endif}
533 End; {Delay}
534
535Initialization
536 GlobalCritSec.Create('');
537 GlobalMutex.Create(False, '', False);
538Finalization
539 GlobalMutex.Destroy;
540 GlobalCritSec.Destroy;
541End.
542
Note: See TracBrowser for help on using the repository browser.