TROSynchronized SingletonClassFactory Handling

My case is delphi 10.4.1, RO/DA: 10.0.0.1495

I’ve 2 codefirst class in server:

  1. One is default TROClassFactory
  2. One is TROSynchronized SingletonClass

In default TROClassFactory One of the function:;

      CodeSite.Send('Start Acquire Send ID1:'+ClientID.ToString);
      cf:=GetClassFactory('SynFuncService');
      cf.CreateInstance(ClientID, instance);
      synService := TSynFuncService((instance as IInterfaceComponentReference).GetComponent);

      if Supports(instance, IROObjectActivation, objactivation) then begin
        objactivation.OnActivate(ClientID, nil);
        objactivation := nil;
      end;

      RunID := synService.isData2Send;

      if Supports(instance, IROObjectActivation, objactivation) then begin
       objactivation.OnDeactivate(ClientId);
       objactivation := nil;
      end;

      //synService := nil;
      instance := nil;


      CodeSite.Send('Start Acquire Send ID2:'+ClientID.ToString);
      cf:=GetClassFactory('SynFuncService');
      cf.CreateInstance(ClientID, instance);
      synService := TSynFuncService((instance as IInterfaceComponentReference).GetComponent);

      if Supports(instance, IROObjectActivation, objactivation) then begin
        objactivation.OnActivate(ClientID, nil);
        objactivation := nil;
      end;

      RunID := synService.isData2Send;

      if Supports(instance, IROObjectActivation, objactivation) then begin
       objactivation.OnDeactivate(ClientId);
       objactivation := nil;
      end;

      instance := nil;

I suppose each I called instance := Nil. That class lock is free. However, it is not that case. Please advise.

Joe

Hi,

as for me, it works as expected for ROStandardClassFactory and ROSynchronizedSingletonClassFactory:
32005.zip (115.1 KB)

I checked your code, My unit I used differentway to define classfactory. As I use auto covert function to migrate to codefirst , May Be I overlook this case . Currently I used the old way to define the classfactory. if my structure is codefirst but the way to define class factory is old. Any potential Issue?

initialization
RegisterCodeFirstService(TSynFuncService); // fake declaration for RTTI
fClassFactory_SynFuncService := TROSynchronizedSingletonClassFactory.Create(__ServiceName, {$IFDEF FPC}@{$ENDIF}Create_SynFuncService, TRORTTIInvoker);
// fClassFactory_SynFuncService := TROClassFactory.Create(__ServiceName, {$IFDEF FPC}@{$ENDIF}Create_SynFuncService, TSynFuncService_Invoker);
// RegisterForZeroConf(fClassFactory_SynFuncService, ‘_SynFuncService_rosdk._tcp.’);
finalization
UnRegisterClassFactory(fClassFactory_SynFuncService);
fClassFactory_SynFuncService := nil;
end.

I used old way on it and did not use the top section [ROSynchronizedSingletonClassFactory] to define it, any potentail issue on it?

also My version did not have the LocalServiceAccess_Acquire and LocalServiceAccess_Release function.

Any chance it is different?

Hi,

no, it isn’t issue.

yes, it is a bit different:

function LocalServiceAccess_Acquire(aGuid: TGuid; aName: string): IROService;
var
  l_local: IUnknown;
  l_activation: IROObjectActivation;
begin
  GetClassFactory(aName).CreateInstance(aGuid, l_local);
  Check(l_local = nil, err_ClassFactoryDidNotReturnInstance, [aName]);
  try
    if not Supports(l_local, IROService, Result) then Result := nil;
    if (Result <> nil) and Supports(Result, IROObjectActivation, l_activation) then begin
      try
        try
          l_activation.OnActivate(aGuid, nil);
        except
          l_activation.OnDeactivate(aGuid);
          GetClassFactory(aName).ReleaseInstance(aGuid, l_local);
          raise;
        end;
      finally
        l_activation := nil;
      end;
    end;
  finally
    l_local := nil;
  end;
end;

procedure LocalServiceAccess_Release(aGuid: TGuid; aName: string; var aService: IROService);
var
  l_local: IUnknown;
  l_activation: IROObjectActivation;
begin
  if (aService <> nil) and Supports(aService, IROObjectActivation, l_activation) then begin
    l_activation.OnDeactivate(aGuid);
    l_activation := nil;
  end;

  l_local := aService as IInterface;
  GetClassFactory(aName).ReleaseInstance(aGuid, l_local);
  l_local := nil;
  aService := nil;
end;

E2232 Interface ‘IROService’ has no interface identification

In uROClientIntf Unit already have this line

{$IFDEF RO_RTTI_Support}[ROSkipAttribute]{$ENDIF}
IROService = interface(IInvokable)
end;

I hit this error how to solve?

Hi,

this interface is declared as

  IROService = interface(IInvokable)
  ['{DC3E5BBF-004C-4126-BBF1-1876440244B0}']
  end;

P.S. .1495 was released 5 years ago…

as it is old project dont want to upgrade to new. so keeping the old version.