You've already forked lazarus-ccr
service implementation pooling
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@189 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -15,7 +15,7 @@ unit base_service_intf;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, TypInfo, Contnrs;
|
Classes, SysUtils, TypInfo, Contnrs, syncobjs, semaphore;
|
||||||
|
|
||||||
{$INCLUDE wst.inc}
|
{$INCLUDE wst.inc}
|
||||||
{$INCLUDE wst_delphi.inc}
|
{$INCLUDE wst_delphi.inc}
|
||||||
@ -90,6 +90,7 @@ type
|
|||||||
|
|
||||||
IItemFactoryEx = interface(IItemFactory)
|
IItemFactoryEx = interface(IItemFactory)
|
||||||
['{66B77926-7E45-4780-8FFB-FB78625EDC1D}']
|
['{66B77926-7E45-4780-8FFB-FB78625EDC1D}']
|
||||||
|
procedure ReleaseInstance(var AInstance : IInterface);
|
||||||
function GetPropertyManager(
|
function GetPropertyManager(
|
||||||
const APropertyGroup : string;
|
const APropertyGroup : string;
|
||||||
const ACreateIfNotExists : Boolean
|
const ACreateIfNotExists : Boolean
|
||||||
@ -987,26 +988,84 @@ type
|
|||||||
private
|
private
|
||||||
FItemClass : TSimpleFactoryItemClass;
|
FItemClass : TSimpleFactoryItemClass;
|
||||||
protected
|
protected
|
||||||
function CreateInstance():IInterface;
|
function CreateInstance():IInterface;virtual;
|
||||||
|
function GetItemClass() : TSimpleFactoryItemClass;
|
||||||
public
|
public
|
||||||
constructor Create(AItemClass : TSimpleFactoryItemClass);
|
constructor Create(AItemClass : TSimpleFactoryItemClass);
|
||||||
End;
|
End;
|
||||||
|
|
||||||
|
{ TIntfPoolItem }
|
||||||
|
|
||||||
|
TIntfPoolItem = class
|
||||||
|
private
|
||||||
|
FIntf: IInterface;
|
||||||
|
FUsed: Boolean;
|
||||||
|
public
|
||||||
|
constructor Create(AIntf : IInterface; const AUsed : Boolean);
|
||||||
|
destructor Destroy();override;
|
||||||
|
property Intf : IInterface read FIntf;
|
||||||
|
property Used : Boolean read FUsed write FUsed;
|
||||||
|
end;
|
||||||
|
|
||||||
|
TIntfPool = class
|
||||||
|
private
|
||||||
|
FList : TObjectList;
|
||||||
|
FCS : TCriticalSection;
|
||||||
|
FLock : TSemaphoreObject;
|
||||||
|
FFactory : IItemFactory;
|
||||||
|
FMin : PtrInt;
|
||||||
|
FMax : PtrInt;
|
||||||
|
private
|
||||||
|
function CreateNew() : TIntfPoolItem;
|
||||||
|
function TryGet(const AIndex : PtrInt) : Boolean;
|
||||||
|
public
|
||||||
|
constructor Create(
|
||||||
|
const AMin, AMax : PtrInt;
|
||||||
|
AFactory : IItemFactory
|
||||||
|
);
|
||||||
|
destructor Destroy();override;
|
||||||
|
function Get(const ATimeOut : Cardinal) : IInterface;
|
||||||
|
procedure Release(var AItem : IInterface);
|
||||||
|
property Min : PtrInt read FMin;
|
||||||
|
property Max : PtrInt read FMax;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TSimpleItemFactoryEx }
|
{ TSimpleItemFactoryEx }
|
||||||
|
|
||||||
TSimpleItemFactoryEx = class(TSimpleItemFactory,IInterface,IItemFactory,IItemFactoryEx)
|
TSimpleItemFactoryEx = class(TSimpleItemFactory,IInterface,IItemFactory,IItemFactoryEx)
|
||||||
private
|
private
|
||||||
|
FPooled: Boolean;
|
||||||
|
FPoolMax: PtrInt;
|
||||||
|
FPoolMin: PtrInt;
|
||||||
FPropertyNames : TStringList;
|
FPropertyNames : TStringList;
|
||||||
FProperties : IInterfaceList;
|
FProperties : IInterfaceList;
|
||||||
|
FPool : TIntfPool;
|
||||||
|
FTimeOut: PtrUInt;
|
||||||
|
private
|
||||||
|
procedure PreparePool();
|
||||||
|
procedure SetPooled(const AValue: Boolean);
|
||||||
|
procedure SetPoolMax(const AValue: PtrInt);
|
||||||
|
procedure SetPoolMin(const AValue: PtrInt);
|
||||||
protected
|
protected
|
||||||
|
function CreateInstance():IInterface;override;
|
||||||
|
procedure ReleaseInstance(var AInstance : IInterface);virtual;
|
||||||
function GetPropertyManager(
|
function GetPropertyManager(
|
||||||
const APropertyGroup : string;
|
const APropertyGroup : string;
|
||||||
const ACreateIfNotExists : Boolean
|
const ACreateIfNotExists : Boolean
|
||||||
):IPropertyManager;
|
):IPropertyManager;
|
||||||
public
|
public
|
||||||
constructor Create(AItemClass : TSimpleFactoryItemClass);
|
constructor Create(
|
||||||
|
AItemClass : TSimpleFactoryItemClass;
|
||||||
|
const APropsString : string
|
||||||
|
);overload;
|
||||||
|
constructor Create(AItemClass : TSimpleFactoryItemClass);overload;
|
||||||
destructor Destroy();override;
|
destructor Destroy();override;
|
||||||
End;
|
published
|
||||||
|
property PoolMax : PtrInt read FPoolMax write SetPoolMax;
|
||||||
|
property PoolMin : PtrInt read FPoolMin write SetPoolMin;
|
||||||
|
property Pooled : Boolean read FPooled write SetPooled;
|
||||||
|
property TimeOut : PtrUInt read FTimeOut write FTimeOut;
|
||||||
|
end;
|
||||||
|
|
||||||
TTypeRegistryItemOption = ( trioNonVisibleToMetadataService );
|
TTypeRegistryItemOption = ( trioNonVisibleToMetadataService );
|
||||||
TTypeRegistryItemOptions = set of TTypeRegistryItemOption;
|
TTypeRegistryItemOptions = set of TTypeRegistryItemOption;
|
||||||
@ -1107,6 +1166,7 @@ const
|
|||||||
function IsStoredPropClass(AClass : TClass;PropInfo : PPropInfo) : TPropStoreType;
|
function IsStoredPropClass(AClass : TClass;PropInfo : PPropInfo) : TPropStoreType;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
uses imp_utils;
|
||||||
|
|
||||||
Var
|
Var
|
||||||
TypeRegistryInstance : TTypeRegistry = Nil;
|
TypeRegistryInstance : TTypeRegistry = Nil;
|
||||||
@ -1999,6 +2059,11 @@ begin
|
|||||||
Result := FItemClass.Create() as IInterface;
|
Result := FItemClass.Create() as IInterface;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TSimpleItemFactory.GetItemClass(): TSimpleFactoryItemClass;
|
||||||
|
begin
|
||||||
|
Result := FItemClass;
|
||||||
|
end;
|
||||||
|
|
||||||
constructor TSimpleItemFactory.Create(AItemClass: TSimpleFactoryItemClass);
|
constructor TSimpleItemFactory.Create(AItemClass: TSimpleFactoryItemClass);
|
||||||
begin
|
begin
|
||||||
Assert(Assigned(AItemClass));
|
Assert(Assigned(AItemClass));
|
||||||
@ -2007,6 +2072,62 @@ end;
|
|||||||
|
|
||||||
{ TSimpleItemFactoryEx }
|
{ TSimpleItemFactoryEx }
|
||||||
|
|
||||||
|
procedure TSimpleItemFactoryEx.PreparePool();
|
||||||
|
begin
|
||||||
|
if ( FPool = nil ) then begin
|
||||||
|
FPool := TIntfPool.Create(PoolMin,PoolMax,TSimpleItemFactory.Create(FItemClass));
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TSimpleItemFactoryEx.SetPooled(const AValue: Boolean);
|
||||||
|
begin
|
||||||
|
if ( FPooled = AValue ) then
|
||||||
|
Exit;
|
||||||
|
FreeAndNil(FPool);
|
||||||
|
if AValue then begin
|
||||||
|
if ( PoolMin < 0 ) or ( PoolMin > PoolMax ) or ( PoolMax < 1 ) then
|
||||||
|
raise EServiceException.Create('Invalid pool parametters.');
|
||||||
|
PreparePool();
|
||||||
|
end;
|
||||||
|
FPooled := AValue;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TSimpleItemFactoryEx.SetPoolMax(const AValue: PtrInt);
|
||||||
|
begin
|
||||||
|
if ( FPoolMax = AValue ) then
|
||||||
|
Exit;
|
||||||
|
if Pooled then
|
||||||
|
raise EServiceException.Create('Operation not allowed on an active pool.');
|
||||||
|
FPoolMax := AValue;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TSimpleItemFactoryEx.SetPoolMin(const AValue: PtrInt);
|
||||||
|
begin
|
||||||
|
if ( FPoolMin = AValue ) then
|
||||||
|
Exit;
|
||||||
|
if Pooled then
|
||||||
|
raise EServiceException.Create('Operation not allowed on an active pool.');
|
||||||
|
FPoolMin := AValue;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TSimpleItemFactoryEx.CreateInstance(): IInterface;
|
||||||
|
begin
|
||||||
|
if Pooled then begin
|
||||||
|
Result := FPool.Get(TimeOut);
|
||||||
|
end else begin
|
||||||
|
Result := inherited CreateInstance();
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TSimpleItemFactoryEx.ReleaseInstance(var AInstance: IInterface);
|
||||||
|
begin
|
||||||
|
if Pooled then begin
|
||||||
|
FPool.Release(AInstance);
|
||||||
|
end else begin
|
||||||
|
AInstance := nil;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
function TSimpleItemFactoryEx.GetPropertyManager(
|
function TSimpleItemFactoryEx.GetPropertyManager(
|
||||||
const APropertyGroup : string;
|
const APropertyGroup : string;
|
||||||
const ACreateIfNotExists : Boolean
|
const ACreateIfNotExists : Boolean
|
||||||
@ -2022,22 +2143,37 @@ begin
|
|||||||
if not ACreateIfNotExists then
|
if not ACreateIfNotExists then
|
||||||
Exit;
|
Exit;
|
||||||
i := FPropertyNames.Add(s);
|
i := FPropertyNames.Add(s);
|
||||||
|
if ( s = '' ) then
|
||||||
|
FProperties.Add(TPublishedPropertyManager.Create(Self) as IInterface)
|
||||||
|
else
|
||||||
FProperties.Add(TStoredPropertyManager.Create() as IInterface);
|
FProperties.Add(TStoredPropertyManager.Create() as IInterface);
|
||||||
end;
|
end;
|
||||||
Result := FProperties.Get(i) as IPropertyManager;
|
Result := FProperties.Get(i) as IPropertyManager;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
constructor TSimpleItemFactoryEx.Create(AItemClass: TSimpleFactoryItemClass);
|
constructor TSimpleItemFactoryEx.Create(
|
||||||
|
AItemClass : TSimpleFactoryItemClass;
|
||||||
|
const APropsString : string
|
||||||
|
);
|
||||||
begin
|
begin
|
||||||
inherited Create(AItemClass);
|
inherited Create(AItemClass);
|
||||||
FPropertyNames := TStringList.Create();
|
FPropertyNames := TStringList.Create();
|
||||||
FProperties := TInterfaceList.Create();
|
FProperties := TInterfaceList.Create();
|
||||||
|
if ( Length(APropsString) > 0 ) then begin
|
||||||
|
GetPropertyManager('',True).SetProperties(APropsString);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
constructor TSimpleItemFactoryEx.Create(AItemClass: TSimpleFactoryItemClass);
|
||||||
|
begin
|
||||||
|
Create(AItemClass,'');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
destructor TSimpleItemFactoryEx.Destroy();
|
destructor TSimpleItemFactoryEx.Destroy();
|
||||||
begin
|
begin
|
||||||
FreeAndNil(FPropertyNames);
|
FreeAndNil(FPropertyNames);
|
||||||
FProperties := nil;
|
FProperties := nil;
|
||||||
|
FreeAndNil(FPool);
|
||||||
inherited Destroy();
|
inherited Destroy();
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -4138,6 +4274,110 @@ begin
|
|||||||
(AObject as TComplexBooleanContentRemotable).Value := i;
|
(AObject as TComplexBooleanContentRemotable).Value := i;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TIntfPoolItem }
|
||||||
|
|
||||||
|
constructor TIntfPoolItem.Create(AIntf: IInterface; const AUsed: Boolean);
|
||||||
|
begin
|
||||||
|
FIntf := AIntf;
|
||||||
|
FUsed := AUsed;
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TIntfPoolItem.Destroy();
|
||||||
|
begin
|
||||||
|
FIntf := nil;
|
||||||
|
inherited Destroy();
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TIntfPool }
|
||||||
|
|
||||||
|
function TIntfPool.CreateNew(): TIntfPoolItem;
|
||||||
|
begin
|
||||||
|
FCS.Acquire();
|
||||||
|
try
|
||||||
|
Result := TIntfPoolItem.Create(FFactory.CreateInstance(),True);
|
||||||
|
FList.Add(Result);
|
||||||
|
finally
|
||||||
|
FCS.Release();
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TIntfPool.TryGet(const AIndex: PtrInt): Boolean;
|
||||||
|
var
|
||||||
|
itm : TIntfPoolItem;
|
||||||
|
begin
|
||||||
|
FCS.Acquire();
|
||||||
|
try
|
||||||
|
itm := TIntfPoolItem(FList[AIndex]);
|
||||||
|
Result := not itm.Used;
|
||||||
|
if Result then begin
|
||||||
|
itm.Used := True;
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
FCS.Release();
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
constructor TIntfPool.Create(
|
||||||
|
const AMin, AMax : PtrInt;
|
||||||
|
AFactory : IItemFactory
|
||||||
|
);
|
||||||
|
var
|
||||||
|
i : PtrInt;
|
||||||
|
begin
|
||||||
|
Assert( ( AMin >= 0 ) and ( AMax >= AMin ) and ( AFactory <> nil ) );
|
||||||
|
FMax := AMax;
|
||||||
|
FMin := AMin;
|
||||||
|
FFactory := AFactory;
|
||||||
|
FLock := TSemaphoreObject.Create(FMax);
|
||||||
|
FList := TObjectList.Create(True);
|
||||||
|
FCS := TCriticalSection.Create();
|
||||||
|
for i := 0 to Pred(AMin) do begin
|
||||||
|
CreateNew();
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TIntfPool.Destroy();
|
||||||
|
begin
|
||||||
|
FFactory := nil;
|
||||||
|
FreeAndNil(FCS);
|
||||||
|
FreeAndNil(FLock);
|
||||||
|
FreeAndNil(FList);
|
||||||
|
inherited Destroy();
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TIntfPool.Get(const ATimeOut : Cardinal): IInterface;
|
||||||
|
var
|
||||||
|
i : PtrInt;
|
||||||
|
begin
|
||||||
|
Result := nil;
|
||||||
|
if ( FLock.WaitFor(ATimeOut) = wrSignaled ) then begin
|
||||||
|
for i := 0 to Pred(FList.Count) do begin
|
||||||
|
if TryGet(i) then begin
|
||||||
|
Result := TIntfPoolItem(FList[i]).Intf;
|
||||||
|
Break;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
if ( Result = nil ) then begin
|
||||||
|
Result := CreateNew().Intf;
|
||||||
|
end;
|
||||||
|
end else begin
|
||||||
|
raise EServiceException.Create('Unable to create the object : Timeout expired.');
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TIntfPool.Release(var AItem: IInterface);
|
||||||
|
var
|
||||||
|
i : PtrInt;
|
||||||
|
begin
|
||||||
|
for i := 0 to Pred(FList.Count) do begin
|
||||||
|
if ( TIntfPoolItem(FList[i]).Intf = AItem ) then begin
|
||||||
|
TIntfPoolItem(FList[i]).Used := False;
|
||||||
|
AItem := nil;
|
||||||
|
Break;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
initialization
|
initialization
|
||||||
TypeRegistryInstance := TTypeRegistry.Create();
|
TypeRegistryInstance := TTypeRegistry.Create();
|
||||||
SerializeOptionsRegistryInstance := TSerializeOptionsRegistry.Create();
|
SerializeOptionsRegistryInstance := TSerializeOptionsRegistry.Create();
|
||||||
|
@ -96,6 +96,10 @@ begin
|
|||||||
If TryStrToInt64(AValue,int64Val) Then
|
If TryStrToInt64(AValue,int64Val) Then
|
||||||
SetOrdProp(FParent,AName,int64Val);
|
SetOrdProp(FParent,AName,int64Val);
|
||||||
End;
|
End;
|
||||||
|
{$IFDEF FPC}
|
||||||
|
tkBool :
|
||||||
|
SetOrdProp(FParent,AName,Ord(StrToBool(AValue)));
|
||||||
|
{$ENDIF}
|
||||||
End;
|
End;
|
||||||
End;
|
End;
|
||||||
end;
|
end;
|
||||||
|
@ -15,16 +15,23 @@ type
|
|||||||
|
|
||||||
TWSTMetadataService_ServiceBinder=class(TBaseServiceBinder)
|
TWSTMetadataService_ServiceBinder=class(TBaseServiceBinder)
|
||||||
Protected
|
Protected
|
||||||
procedure GetRepositoryListHandler(AFormatter:IFormatterResponse);
|
procedure GetRepositoryListHandler(AFormatter:IFormatterResponse; AContext : ICallContext);
|
||||||
procedure GetRepositoryInfoHandler(AFormatter:IFormatterResponse);
|
procedure GetRepositoryInfoHandler(AFormatter:IFormatterResponse; AContext : ICallContext);
|
||||||
Public
|
Public
|
||||||
constructor Create();
|
constructor Create();
|
||||||
End;
|
End;
|
||||||
|
|
||||||
|
{ TWSTMetadataService_ServiceBinderFactory }
|
||||||
|
|
||||||
TWSTMetadataService_ServiceBinderFactory = class(TInterfacedObject,IItemFactory)
|
TWSTMetadataService_ServiceBinderFactory = class(TInterfacedObject,IItemFactory)
|
||||||
|
private
|
||||||
|
FInstance : IInterface;
|
||||||
protected
|
protected
|
||||||
function CreateInstance():IInterface;
|
function CreateInstance():IInterface;
|
||||||
End;
|
public
|
||||||
|
constructor Create();
|
||||||
|
destructor Destroy();override;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure Server_service_RegisterWSTMetadataServiceService();
|
procedure Server_service_RegisterWSTMetadataServiceService();
|
||||||
|
|
||||||
@ -32,7 +39,7 @@ Implementation
|
|||||||
uses TypInfo, wst_resources_imp,metadata_repository;
|
uses TypInfo, wst_resources_imp,metadata_repository;
|
||||||
|
|
||||||
{ TWSTMetadataService_ServiceBinder implementation }
|
{ TWSTMetadataService_ServiceBinder implementation }
|
||||||
procedure TWSTMetadataService_ServiceBinder.GetRepositoryListHandler(AFormatter:IFormatterResponse);
|
procedure TWSTMetadataService_ServiceBinder.GetRepositoryListHandler(AFormatter:IFormatterResponse; AContext : ICallContext);
|
||||||
Var
|
Var
|
||||||
cllCntrl : ICallControl;
|
cllCntrl : ICallControl;
|
||||||
tmpObj : IWSTMetadataService;
|
tmpObj : IWSTMetadataService;
|
||||||
@ -41,14 +48,14 @@ Var
|
|||||||
procName,trgName : string;
|
procName,trgName : string;
|
||||||
returnVal : TArrayOfStringRemotable;
|
returnVal : TArrayOfStringRemotable;
|
||||||
Begin
|
Begin
|
||||||
callCtx := GetCallContext();
|
callCtx := AContext;
|
||||||
If ( PTypeInfo(TypeInfo(TArrayOfStringRemotable))^.Kind in [tkClass,tkInterface] ) Then
|
If ( PTypeInfo(TypeInfo(TArrayOfStringRemotable))^.Kind in [tkClass,tkInterface] ) Then
|
||||||
Pointer(returnVal) := Nil;
|
Pointer(returnVal) := Nil;
|
||||||
|
|
||||||
|
|
||||||
tmpObj := Self.GetFactory().CreateInstance() as IWSTMetadataService;
|
tmpObj := Self.GetFactory().CreateInstance() as IWSTMetadataService;
|
||||||
if Supports(tmpObj,ICallControl,cllCntrl) then
|
if Supports(tmpObj,ICallControl,cllCntrl) then
|
||||||
cllCntrl.SetCallContext(GetCallContext());
|
cllCntrl.SetCallContext(callCtx);
|
||||||
|
|
||||||
returnVal := tmpObj.GetRepositoryList();
|
returnVal := tmpObj.GetRepositoryList();
|
||||||
If ( PTypeInfo(TypeInfo(TArrayOfStringRemotable))^.Kind = tkClass ) And Assigned(Pointer(returnVal)) Then
|
If ( PTypeInfo(TypeInfo(TArrayOfStringRemotable))^.Kind = tkClass ) And Assigned(Pointer(returnVal)) Then
|
||||||
@ -64,7 +71,7 @@ Begin
|
|||||||
callCtx := Nil;
|
callCtx := Nil;
|
||||||
End;
|
End;
|
||||||
|
|
||||||
procedure TWSTMetadataService_ServiceBinder.GetRepositoryInfoHandler(AFormatter:IFormatterResponse);
|
procedure TWSTMetadataService_ServiceBinder.GetRepositoryInfoHandler(AFormatter:IFormatterResponse; AContext : ICallContext);
|
||||||
Var
|
Var
|
||||||
cllCntrl : ICallControl;
|
cllCntrl : ICallControl;
|
||||||
tmpObj : IWSTMetadataService;
|
tmpObj : IWSTMetadataService;
|
||||||
@ -74,14 +81,14 @@ Var
|
|||||||
AName : string;
|
AName : string;
|
||||||
returnVal : TWSTMtdRepository;
|
returnVal : TWSTMtdRepository;
|
||||||
Begin
|
Begin
|
||||||
callCtx := GetCallContext();
|
callCtx := AContext;
|
||||||
Pointer(returnVal) := Nil;
|
Pointer(returnVal) := Nil;
|
||||||
|
|
||||||
strPrmName := 'AName'; AFormatter.Get(TypeInfo(string),strPrmName,AName);
|
strPrmName := 'AName'; AFormatter.Get(TypeInfo(string),strPrmName,AName);
|
||||||
|
|
||||||
tmpObj := Self.GetFactory().CreateInstance() as IWSTMetadataService;
|
tmpObj := Self.GetFactory().CreateInstance() as IWSTMetadataService;
|
||||||
if Supports(tmpObj,ICallControl,cllCntrl) then
|
if Supports(tmpObj,ICallControl,cllCntrl) then
|
||||||
cllCntrl.SetCallContext(GetCallContext());
|
cllCntrl.SetCallContext(callCtx);
|
||||||
|
|
||||||
returnVal := tmpObj.GetRepositoryInfo(AName);
|
returnVal := tmpObj.GetRepositoryInfo(AName);
|
||||||
If Assigned(Pointer(returnVal)) Then
|
If Assigned(Pointer(returnVal)) Then
|
||||||
@ -109,9 +116,20 @@ End;
|
|||||||
{ TWSTMetadataService_ServiceBinderFactory }
|
{ TWSTMetadataService_ServiceBinderFactory }
|
||||||
function TWSTMetadataService_ServiceBinderFactory.CreateInstance():IInterface;
|
function TWSTMetadataService_ServiceBinderFactory.CreateInstance():IInterface;
|
||||||
Begin
|
Begin
|
||||||
Result := TWSTMetadataService_ServiceBinder.Create() as IInterface;
|
Result := FInstance;
|
||||||
End;
|
End;
|
||||||
|
|
||||||
|
constructor TWSTMetadataService_ServiceBinderFactory.Create();
|
||||||
|
begin
|
||||||
|
FInstance := TWSTMetadataService_ServiceBinder.Create();
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TWSTMetadataService_ServiceBinderFactory.Destroy();
|
||||||
|
begin
|
||||||
|
FInstance := nil;
|
||||||
|
inherited Destroy();
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure Server_service_RegisterWSTMetadataServiceService();
|
procedure Server_service_RegisterWSTMetadataServiceService();
|
||||||
Begin
|
Begin
|
||||||
|
@ -577,7 +577,7 @@ procedure TBaseComplexRemotable_TypeHandler.Generate(
|
|||||||
var
|
var
|
||||||
typItm, propTypItm : TTypeRegistryItem;
|
typItm, propTypItm : TTypeRegistryItem;
|
||||||
s, prop_ns_shortName : string;
|
s, prop_ns_shortName : string;
|
||||||
defTypesNode, defSchemaNode, cplxNode, sqcNode, propNode, eltNode : TDOMElement;
|
defTypesNode, defSchemaNode, cplxNode, sqcNode, propNode : TDOMElement;
|
||||||
i : Integer;
|
i : Integer;
|
||||||
propList : PPropList;
|
propList : PPropList;
|
||||||
propCount, propListLen : Integer;
|
propCount, propListLen : Integer;
|
||||||
@ -596,13 +596,10 @@ begin
|
|||||||
Assert(Assigned(defTypesNode));
|
Assert(Assigned(defTypesNode));
|
||||||
defSchemaNode := defTypesNode.FirstChild as TDOMElement;
|
defSchemaNode := defTypesNode.FirstChild as TDOMElement;
|
||||||
|
|
||||||
s := Format('%s:%s',[sXSD,sELEMENT]);
|
|
||||||
eltNode := CreateElement(s,defSchemaNode,AWsdlDocument);
|
|
||||||
eltNode.SetAttribute(sNAME, typItm.DeclaredName) ;
|
|
||||||
|
|
||||||
s := Format('%s:%s',[sXSD,sCOMPLEX_TYPE]);
|
s := Format('%s:%s',[sXSD,sCOMPLEX_TYPE]);
|
||||||
cplxNode := CreateElement(s,eltNode,AWsdlDocument);
|
cplxNode := CreateElement(s,defSchemaNode,AWsdlDocument);
|
||||||
//cplxNode.SetAttribute(sNAME, typItm.DeclaredName) ;
|
cplxNode.SetAttribute(sNAME, typItm.DeclaredName) ;
|
||||||
|
|
||||||
s := Format('%s:%s',[sXSD,sSEQUENCE]);
|
s := Format('%s:%s',[sXSD,sSEQUENCE]);
|
||||||
sqcNode := CreateElement(s,cplxNode,AWsdlDocument);
|
sqcNode := CreateElement(s,cplxNode,AWsdlDocument);
|
||||||
objTypeData := GetTypeData(typItm.DataType);
|
objTypeData := GetTypeData(typItm.DataType);
|
||||||
@ -623,7 +620,7 @@ begin
|
|||||||
s := Format('%s:%s',[sXSD,sELEMENT]);
|
s := Format('%s:%s',[sXSD,sELEMENT]);
|
||||||
propNode := CreateElement(s,sqcNode,AWsdlDocument);
|
propNode := CreateElement(s,sqcNode,AWsdlDocument);
|
||||||
end;
|
end;
|
||||||
propNode.SetAttribute(sNAME,p^.Name);
|
propNode.SetAttribute(sNAME,typItm.GetExternalPropertyName(p^.Name));
|
||||||
propTypItm := GetTypeRegistry().Find(p^.PropType^.Name);
|
propTypItm := GetTypeRegistry().Find(p^.PropType^.Name);
|
||||||
if Assigned(propTypItm) then begin
|
if Assigned(propTypItm) then begin
|
||||||
prop_ns_shortName := GetNameSpaceShortName(propTypItm.NameSpace,AWsdlDocument);
|
prop_ns_shortName := GetNameSpaceShortName(propTypItm.NameSpace,AWsdlDocument);
|
||||||
@ -775,7 +772,7 @@ procedure TBaseArrayRemotable_TypeHandler.Generate(
|
|||||||
var
|
var
|
||||||
typItm, propTypItm : TTypeRegistryItem;
|
typItm, propTypItm : TTypeRegistryItem;
|
||||||
s, prop_ns_shortName : string;
|
s, prop_ns_shortName : string;
|
||||||
defTypesNode, defSchemaNode, cplxNode, sqcNode, propNode, eltNode : TDOMElement;
|
defTypesNode, defSchemaNode, cplxNode, sqcNode, propNode : TDOMElement;
|
||||||
arrayTypeData : PTypeData;
|
arrayTypeData : PTypeData;
|
||||||
arrayTypeClass : TBaseArrayRemotableClass;
|
arrayTypeClass : TBaseArrayRemotableClass;
|
||||||
begin
|
begin
|
||||||
@ -792,13 +789,10 @@ begin
|
|||||||
Assert(Assigned(defTypesNode));
|
Assert(Assigned(defTypesNode));
|
||||||
defSchemaNode := defTypesNode.FirstChild as TDOMElement;
|
defSchemaNode := defTypesNode.FirstChild as TDOMElement;
|
||||||
|
|
||||||
s := Format('%s:%s',[sXSD,sELEMENT]);
|
|
||||||
eltNode := CreateElement(s,defSchemaNode,AWsdlDocument);
|
|
||||||
eltNode.SetAttribute(sNAME, typItm.DeclaredName) ;
|
|
||||||
|
|
||||||
s := Format('%s:%s',[sXSD,sCOMPLEX_TYPE]);
|
s := Format('%s:%s',[sXSD,sCOMPLEX_TYPE]);
|
||||||
cplxNode := CreateElement(s,eltNode,AWsdlDocument);
|
cplxNode := CreateElement(s,defSchemaNode,AWsdlDocument);
|
||||||
//cplxNode.SetAttribute(sNAME, typItm.DeclaredName) ;
|
cplxNode.SetAttribute(sNAME, typItm.DeclaredName) ;
|
||||||
|
|
||||||
s := Format('%s:%s',[sXSD,sSEQUENCE]);
|
s := Format('%s:%s',[sXSD,sSEQUENCE]);
|
||||||
sqcNode := CreateElement(s,cplxNode,AWsdlDocument);
|
sqcNode := CreateElement(s,cplxNode,AWsdlDocument);
|
||||||
arrayTypeClass := TBaseArrayRemotableClass(arrayTypeData^.ClassType);
|
arrayTypeClass := TBaseArrayRemotableClass(arrayTypeData^.ClassType);
|
||||||
|
99
wst/trunk/semaphore.pas
Normal file
99
wst/trunk/semaphore.pas
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
unit semaphore;
|
||||||
|
|
||||||
|
{$mode objfpc}{$H+}
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
Classes, SysUtils, syncobjs;
|
||||||
|
|
||||||
|
type
|
||||||
|
|
||||||
|
ESemaphoreException = class(Exception);
|
||||||
|
|
||||||
|
{ TSemaphoreObject }
|
||||||
|
|
||||||
|
TSemaphoreObject = class
|
||||||
|
private
|
||||||
|
FHandle : PRTLEvent;
|
||||||
|
FLimit: Integer;
|
||||||
|
FCurrentState : Integer;
|
||||||
|
FCriticalSection : TCriticalSection;
|
||||||
|
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;
|
||||||
|
FHandle := RTLEventCreate();
|
||||||
|
FCriticalSection := TCriticalSection.Create();
|
||||||
|
FCurrentState := FLimit;
|
||||||
|
RTLeventSetEvent(FHandle);
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TSemaphoreObject.Destroy();
|
||||||
|
begin
|
||||||
|
RTLeventdestroy(FHandle);
|
||||||
|
FreeAndNil(FCriticalSection);
|
||||||
|
inherited Destroy();
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TSemaphoreObject.WaitFor(ATimeout: Cardinal): TWaitResult;
|
||||||
|
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;
|
||||||
|
|
||||||
|
procedure TSemaphoreObject.Release();
|
||||||
|
begin
|
||||||
|
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);
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
||||||
|
|
@ -33,6 +33,7 @@ Type
|
|||||||
|
|
||||||
IServiceExtension = interface;
|
IServiceExtension = interface;
|
||||||
IServiceExtensionRegistry = interface;
|
IServiceExtensionRegistry = interface;
|
||||||
|
IObjectControl = interface;
|
||||||
|
|
||||||
ICallControl = interface
|
ICallControl = interface
|
||||||
['{7B4B7192-EE96-4B52-92C7-AE855FBC31E7}']
|
['{7B4B7192-EE96-4B52-92C7-AE855FBC31E7}']
|
||||||
@ -122,15 +123,21 @@ Type
|
|||||||
procedure EndExceptionList();
|
procedure EndExceptionList();
|
||||||
End;
|
End;
|
||||||
|
|
||||||
TServiceVerbMethod = procedure(AFormatter:IFormatterResponse) of object;
|
IObjectControl = interface
|
||||||
|
['{C422C7CA-4C95-48A4-9A82-2616E619F851}']
|
||||||
|
procedure Activate();
|
||||||
|
procedure Deactivate();
|
||||||
|
function CanBePooled() : Boolean;
|
||||||
|
end;
|
||||||
|
|
||||||
|
TServiceVerbMethod = procedure(AFormatter:IFormatterResponse; AContext : ICallContext) of object;
|
||||||
|
|
||||||
{ TBaseServiceBinder }
|
{ TBaseServiceBinder }
|
||||||
|
|
||||||
TBaseServiceBinder = Class(TInterfacedObject,IServerService)
|
TBaseServiceBinder = Class(TInterfacedPersistent,IServerService)
|
||||||
Private
|
Private
|
||||||
FVerbList : TObjectList;
|
FVerbList : TObjectList;
|
||||||
FImplementationFactory : IServiceImplementationFactory;
|
FImplementationFactory : IServiceImplementationFactory;
|
||||||
FCallContext : ICallContext;
|
|
||||||
Protected
|
Protected
|
||||||
procedure RegisterVerbHandler(
|
procedure RegisterVerbHandler(
|
||||||
const AVerb : string;
|
const AVerb : string;
|
||||||
@ -138,9 +145,8 @@ Type
|
|||||||
);
|
);
|
||||||
function FindVerbHandler(const AVerb : string):TServiceVerbMethod;
|
function FindVerbHandler(const AVerb : string):TServiceVerbMethod;
|
||||||
procedure HandleRequest(ARequestBuffer : IRequestBuffer);
|
procedure HandleRequest(ARequestBuffer : IRequestBuffer);
|
||||||
function GetFactory():IItemFactory;
|
function GetFactory():IServiceImplementationFactory;
|
||||||
function CreateCallContext():ICallContext;virtual;
|
function CreateCallContext():ICallContext;virtual;
|
||||||
function GetCallContext():ICallContext;
|
|
||||||
procedure DoProcessMessage(
|
procedure DoProcessMessage(
|
||||||
const AMessageStage : TMessageStage;
|
const AMessageStage : TMessageStage;
|
||||||
ACallContext : ICallContext;
|
ACallContext : ICallContext;
|
||||||
@ -163,6 +169,14 @@ Type
|
|||||||
function GetCallContext():ICallContext;
|
function GetCallContext():ICallContext;
|
||||||
End;
|
End;
|
||||||
|
|
||||||
|
{ TActivableServiceImplementation }
|
||||||
|
|
||||||
|
TActivableServiceImplementation = class(TBaseServiceImplementation,IObjectControl)
|
||||||
|
protected
|
||||||
|
procedure Activate();virtual;
|
||||||
|
procedure Deactivate();virtual;
|
||||||
|
function CanBePooled() : Boolean;virtual;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TImplementationFactory }
|
{ TImplementationFactory }
|
||||||
|
|
||||||
@ -332,17 +346,17 @@ begin
|
|||||||
if not Assigned(f) then
|
if not Assigned(f) then
|
||||||
Error('No formatter for that content type : "%s"',[s]);
|
Error('No formatter for that content type : "%s"',[s]);
|
||||||
try
|
try
|
||||||
cllCtx := GetCallContext();
|
cllCtx := CreateCallContext();
|
||||||
DoProcessMessage(msBeforeDeserialize,cllCtx,ARequestBuffer);
|
DoProcessMessage(msBeforeDeserialize,cllCtx,ARequestBuffer);
|
||||||
strm := ARequestBuffer.GetContent();
|
strm := ARequestBuffer.GetContent();
|
||||||
f.LoadFromStream(strm);
|
f.LoadFromStream(strm);
|
||||||
f.BeginCallRead(GetCallContext());
|
f.BeginCallRead(cllCtx);
|
||||||
DoProcessMessage(msAfterDeserialize,cllCtx,f);
|
DoProcessMessage(msAfterDeserialize,cllCtx,f);
|
||||||
s := f.GetCallProcedureName();
|
s := f.GetCallProcedureName();
|
||||||
m := FindVerbHandler(s);
|
m := FindVerbHandler(s);
|
||||||
if not Assigned(m) then
|
if not Assigned(m) then
|
||||||
Error('No handler for that verb : "%s"',[s]);
|
Error('No handler for that verb : "%s"',[s]);
|
||||||
m(f);
|
m(f,cllCtx);
|
||||||
for i := 0 to Pred(cllCtx.GetHeaderCount(AllHeaderDirection)) do begin
|
for i := 0 to Pred(cllCtx.GetHeaderCount(AllHeaderDirection)) do begin
|
||||||
hdr := cllCtx.GetHeader(i);
|
hdr := cllCtx.GetHeader(i);
|
||||||
if ( hdr.Direction = hdIn ) and ( hdr.mustUnderstand <> 0 ) and ( not hdr.Understood ) then begin
|
if ( hdr.Direction = hdIn ) and ( hdr.mustUnderstand <> 0 ) and ( not hdr.Understood ) then begin
|
||||||
@ -368,23 +382,14 @@ begin
|
|||||||
DoProcessMessage(msAfterSerialize,cllCtx,ARequestBuffer);
|
DoProcessMessage(msAfterSerialize,cllCtx,ARequestBuffer);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TBaseServiceBinder.GetFactory(): IItemFactory;
|
function TBaseServiceBinder.GetFactory(): IServiceImplementationFactory;
|
||||||
begin
|
begin
|
||||||
Result := FImplementationFactory;
|
Result := FImplementationFactory;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TBaseServiceBinder.CreateCallContext(): ICallContext;
|
function TBaseServiceBinder.CreateCallContext(): ICallContext;
|
||||||
begin
|
begin
|
||||||
if not Assigned(FCallContext) then
|
Result := TSimpleCallContext.Create() as ICallContext;
|
||||||
FCallContext := TSimpleCallContext.Create() as ICallContext;
|
|
||||||
Result := FCallContext;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TBaseServiceBinder.GetCallContext(): ICallContext;
|
|
||||||
begin
|
|
||||||
if not Assigned(FCallContext) then
|
|
||||||
CreateCallContext();
|
|
||||||
Result := FCallContext;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TBaseServiceBinder.DoProcessMessage(
|
procedure TBaseServiceBinder.DoProcessMessage(
|
||||||
@ -421,6 +426,7 @@ end;
|
|||||||
constructor TBaseServiceBinder.Create(AImplementationFactory : IServiceImplementationFactory);
|
constructor TBaseServiceBinder.Create(AImplementationFactory : IServiceImplementationFactory);
|
||||||
begin
|
begin
|
||||||
Assert(Assigned(AImplementationFactory));
|
Assert(Assigned(AImplementationFactory));
|
||||||
|
inherited Create();
|
||||||
FImplementationFactory := AImplementationFactory;
|
FImplementationFactory := AImplementationFactory;
|
||||||
FVerbList := TObjectList.Create(True);
|
FVerbList := TObjectList.Create(True);
|
||||||
end;
|
end;
|
||||||
@ -554,6 +560,7 @@ end;
|
|||||||
|
|
||||||
{ TImplementationFactory }
|
{ TImplementationFactory }
|
||||||
const sSERVICES_EXTENSIONS = 'extensions';sLIST = 'list';
|
const sSERVICES_EXTENSIONS = 'extensions';sLIST = 'list';
|
||||||
|
|
||||||
procedure TImplementationFactory.RegisterExtension(
|
procedure TImplementationFactory.RegisterExtension(
|
||||||
const AExtensionList : array of string
|
const AExtensionList : array of string
|
||||||
);
|
);
|
||||||
@ -621,6 +628,23 @@ begin
|
|||||||
Result := ServiceExtensionRegistryInst;
|
Result := ServiceExtensionRegistryInst;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TActivableServiceImplementation }
|
||||||
|
|
||||||
|
procedure TActivableServiceImplementation.Activate();
|
||||||
|
begin
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TActivableServiceImplementation.Deactivate();
|
||||||
|
begin
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TActivableServiceImplementation.CanBePooled(): Boolean;
|
||||||
|
begin
|
||||||
|
Result := False;
|
||||||
|
end;
|
||||||
|
|
||||||
Initialization
|
Initialization
|
||||||
FormatterRegistryInst := TFormatterRegistry.Create() as IFormatterRegistry;
|
FormatterRegistryInst := TFormatterRegistry.Create() as IFormatterRegistry;
|
||||||
ServerServiceRegistryInst := TServerServiceRegistry.Create() as IServerServiceRegistry;
|
ServerServiceRegistryInst := TServerServiceRegistry.Create() as IServerServiceRegistry;
|
||||||
|
Reference in New Issue
Block a user