2007-07-12 14:46:45 +00:00
|
|
|
{
|
|
|
|
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}
|
2007-06-24 15:32:38 +00:00
|
|
|
unit semaphore;
|
|
|
|
|
|
|
|
interface
|
|
|
|
|
|
|
|
uses
|
2008-06-06 14:45:19 +00:00
|
|
|
Classes, SysUtils, SyncObjs, wst_types
|
|
|
|
{$IFDEF WST_DELPHI}
|
|
|
|
,Windows
|
|
|
|
{$ENDIF}
|
|
|
|
{$IFDEF FPC}
|
|
|
|
{$IFDEF WINDOWS}
|
|
|
|
,Windows
|
|
|
|
{$ENDIF}
|
|
|
|
{$ENDIF};
|
2007-07-12 14:46:45 +00:00
|
|
|
|
2007-06-24 15:32:38 +00:00
|
|
|
type
|
|
|
|
|
|
|
|
ESemaphoreException = class(Exception);
|
2007-07-12 14:46:45 +00:00
|
|
|
|
2008-06-06 14:45:19 +00:00
|
|
|
{$UNDEF FPC_TM}
|
|
|
|
{$IFDEF WST_DELPHI}
|
|
|
|
TSemaphoreHandle = THandle;
|
|
|
|
{$ENDIF}
|
|
|
|
{$IFDEF FPC}
|
|
|
|
{$IFDEF WINDOWS}
|
|
|
|
TSemaphoreHandle = THandle;
|
|
|
|
{$ELSE}
|
|
|
|
{$DEFINE FPC_TM}
|
|
|
|
TSemaphoreHandle = Pointer;
|
|
|
|
{$ENDIF}
|
|
|
|
{$ENDIF}
|
|
|
|
|
2007-06-24 15:32:38 +00:00
|
|
|
{ TSemaphoreObject }
|
|
|
|
|
|
|
|
TSemaphoreObject = class
|
|
|
|
private
|
2008-06-06 14:45:19 +00:00
|
|
|
FHandle : TSemaphoreHandle;
|
2007-06-24 15:32:38 +00:00
|
|
|
FLimit: Integer;
|
2008-06-06 14:45:19 +00:00
|
|
|
{$IFDEF FPC_TM}
|
|
|
|
FTM : TThreadManager;
|
|
|
|
{$ENDIF}
|
2007-06-24 15:32:38 +00:00
|
|
|
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);
|
2008-06-06 14:45:19 +00:00
|
|
|
var
|
|
|
|
i : PtrInt;
|
2007-06-24 15:32:38 +00:00
|
|
|
begin
|
2008-06-06 14:45:19 +00:00
|
|
|
if ( ALimit < 1 ) then
|
|
|
|
raise ESemaphoreException.CreateFmt('Invalid semaphore maximum count : %d.',[ALimit]);
|
2007-06-24 15:32:38 +00:00
|
|
|
FLimit := ALimit;
|
2008-06-06 14:45:19 +00:00
|
|
|
{$IFNDEF FPC_TM}
|
2007-07-12 14:46:45 +00:00
|
|
|
FHandle := CreateSemaphore(nil,ALimit,ALimit,'');
|
2008-06-06 14:45:19 +00:00
|
|
|
if ( FHandle = THandle(0) ) then
|
|
|
|
RaiseLastOSError();
|
2007-07-12 14:46:45 +00:00
|
|
|
{$ELSE}
|
2008-06-06 14:45:19 +00:00
|
|
|
if not GetThreadManager(FTM) then
|
|
|
|
raise ESemaphoreException.Create('Unable to get the thread manager.');
|
|
|
|
FHandle := FTM.SemaphoreInit();
|
|
|
|
for i := 1 to FLimit do
|
|
|
|
FTM.SemaphorePost(FHandle);
|
2007-07-12 14:46:45 +00:00
|
|
|
{$ENDIF}
|
2007-06-24 15:32:38 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
destructor TSemaphoreObject.Destroy();
|
|
|
|
begin
|
2008-06-06 14:45:19 +00:00
|
|
|
{$IFNDEF FPC_TM}
|
|
|
|
if ( FHandle <> THandle(0) ) then
|
|
|
|
CloseHandle(FHandle);
|
2007-07-12 14:46:45 +00:00
|
|
|
{$ELSE}
|
2008-06-06 14:45:19 +00:00
|
|
|
if ( FHandle <> nil ) then
|
|
|
|
FTM.SemaphoreDestroy(FHandle);
|
|
|
|
FHandle := nil;
|
2007-07-12 14:46:45 +00:00
|
|
|
{$ENDIF}
|
2007-06-24 15:32:38 +00:00
|
|
|
inherited Destroy();
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TSemaphoreObject.WaitFor(ATimeout: Cardinal): TWaitResult;
|
2008-06-06 14:45:19 +00:00
|
|
|
{$IFNDEF FPC_TM}
|
2007-07-12 14:46:45 +00:00
|
|
|
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}
|
2007-06-24 15:32:38 +00:00
|
|
|
begin
|
2008-06-06 14:45:19 +00:00
|
|
|
FTM.SemaphoreWait(FHandle);
|
|
|
|
Result := wrSignaled;
|
2007-06-24 15:32:38 +00:00
|
|
|
end;
|
2007-07-12 14:46:45 +00:00
|
|
|
{$ENDIF}
|
2007-06-24 15:32:38 +00:00
|
|
|
|
|
|
|
procedure TSemaphoreObject.Release();
|
|
|
|
begin
|
2008-06-06 14:45:19 +00:00
|
|
|
{$IFNDEF FPC_TM}
|
2007-07-12 14:46:45 +00:00
|
|
|
ReleaseSemaphore(FHandle,1,nil);
|
|
|
|
{$ELSE}
|
2008-06-06 14:45:19 +00:00
|
|
|
FTM.SemaphorePost(FHandle);
|
2007-07-12 14:46:45 +00:00
|
|
|
{$ENDIF}
|
2007-06-24 15:32:38 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
end.
|
|
|
|
|
2008-01-08 17:09:27 +00:00
|
|
|
|