Files
lazarus-ccr/wst/trunk/semaphore.pas
inoussa 11a897fc26 Object Pascal "record" serialization ( first commit! )
TTest_TIntfPoolItem
TTest_TSimpleItemFactory
TTest_XmlRpcFormatterExceptionBlock
TTest_SoapFormatterExceptionBlock
Record serialization test

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@243 8e941d3f-bd1b-0410-a28a-d453659cc2b4
2007-08-19 00:29:43 +00:00

141 lines
2.9 KiB
ObjectPascal

{
This file is part of the Web Service Toolkit
Copyright (c) 2006 by Inoussa OUEDRAOGO
This file is provide under modified LGPL licence
( the files COPYING.modifiedLGPL and COPYING.LGPL).
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
}
{$INCLUDE wst_global.inc}
unit semaphore;
interface
uses
Classes, SysUtils, syncobjs{$IFNDEF FPC},Windows{$ENDIF};
type
ESemaphoreException = class(Exception);
{ TSemaphoreObject }
TSemaphoreObject = class
private
FHandle : {$IFNDEF FPC}THandle{$ELSE}PRTLEvent{$ENDIF};
FLimit: Integer;
{$IFDEF FPC}
FCurrentState : Integer;
FCriticalSection : TCriticalSection;
{$ENDIF}
public
constructor Create(const ALimit : Integer);
destructor Destroy(); override;
function WaitFor(ATimeout : Cardinal) : TWaitResult;
procedure Release();
property Limit : Integer read FLimit;
end;
implementation
{ TSemaphoreObject }
constructor TSemaphoreObject.Create(const ALimit: Integer);
begin
Assert(ALimit>0);
FLimit := ALimit;
{$IFNDEF FPC}
FHandle := CreateSemaphore(nil,ALimit,ALimit,'');
{$ELSE}
FHandle := RTLEventCreate();
FCriticalSection := TCriticalSection.Create();
FCurrentState := FLimit;
RTLeventSetEvent(FHandle);
{$ENDIF}
end;
destructor TSemaphoreObject.Destroy();
begin
{$IFNDEF FPC}
CloseHandle(FHandle);
{$ELSE}
RTLeventdestroy(FHandle);
FreeAndNil(FCriticalSection);
{$ENDIF}
inherited Destroy();
end;
function TSemaphoreObject.WaitFor(ATimeout: Cardinal): TWaitResult;
{$IFNDEF FPC}
var
intRes : DWORD;
begin
intRes := WaitForSingleObject(FHandle,ATimeout);
case intRes of
WAIT_OBJECT_0 : Result := wrSignaled;
WAIT_TIMEOUT : Result := wrTimeout;
WAIT_ABANDONED : Result := wrAbandoned;
else
Result := wrTimeout;
end;
end;
{$ELSE}
var
ok : Boolean;
begin
Result := wrTimeout;
ok := False;
FCriticalSection.Acquire();
try
if ( FCurrentState > 0 ) then begin
Dec(FCurrentState);
ok := True;
if ( FCurrentState = 0 ) then
RTLeventResetEvent(FHandle);
end;
finally
FCriticalSection.Release();
end;
if not ok then begin
RTLeventWaitFor(FHandle,ATimeout);
FCriticalSection.Acquire();
try
if ( FCurrentState > 0 ) then begin
Dec(FCurrentState);
ok := True;
end;
finally
FCriticalSection.Release();
end;
end;
if ok then
Result := wrSignaled;
end;
{$ENDIF}
procedure TSemaphoreObject.Release();
begin
{$IFNDEF FPC}
ReleaseSemaphore(FHandle,1,nil);
{$ELSE}
FCriticalSection.Acquire();
try
if ( FCurrentState < Limit ) then begin
Inc(FCurrentState);
end else begin
raise ESemaphoreException.Create('Invalid semaphore operation.');
end;
finally
FCriticalSection.Release();
end;
RTLeventSetEvent(FHandle);
{$ENDIF}
end;
end.