A Singleton in Delphi Tokyo
A Singleton in Delphi Tokyo
I have some code that appears to have stopped working. We have had every version from XE7 right up until Tokyo and I have a singleton in there for doing Debugging to Log files...... For IPR reason I cannot include the source code, but safe to say I used the pattern described in:
http://edn.embarcadero.com/article/22576
However, we made a few mods, so:
var
debugger: TuexDebugLogger = nil;
debuggerRefCount: Integer = 0;
{*****************************************************************************
* Class : TuexDebugLogger
* Function : NewInstance
* Arguments : None
* Action : Overriden NewInstance for singleton
* Returns : An object pointer
*******************************************************************************}
class function TuexDebugLogger.NewInstance: TObject;
begin
if debugger <> nil then
begin
Result := debugger;
end
else
begin
Result := inherited NewInstance;
end;
Inc( debuggerRefCount );
end;
{******************************************************************************
* Class : TuexDebugLogger
* Function : FreeInstance
* Arguments : None
* Action : Overriden FreeInstance for singleton
* Returns : nothing
********************************************************************************}
procedure TuexDebugLogger.FreeInstance;
begin
Dec( debuggerRefCount );
if debuggerRefCount = 0 then
begin
inherited FreeInstance;
end;
end;
This appeared to be working, but now it isn't and we have several distinct instances, instead of 1 !
Has anyone got any ideas as to why it won't work anymore ?
http://edn.embarcadero.com/article/22576
I have some code that appears to have stopped working. We have had every version from XE7 right up until Tokyo and I have a singleton in there for doing Debugging to Log files...... For IPR reason I cannot include the source code, but safe to say I used the pattern described in:
http://edn.embarcadero.com/article/22576
However, we made a few mods, so:
var
debugger: TuexDebugLogger = nil;
debuggerRefCount: Integer = 0;
{*****************************************************************************
* Class : TuexDebugLogger
* Function : NewInstance
* Arguments : None
* Action : Overriden NewInstance for singleton
* Returns : An object pointer
*******************************************************************************}
class function TuexDebugLogger.NewInstance: TObject;
begin
if debugger <> nil then
begin
Result := debugger;
end
else
begin
Result := inherited NewInstance;
end;
Inc( debuggerRefCount );
end;
{******************************************************************************
* Class : TuexDebugLogger
* Function : FreeInstance
* Arguments : None
* Action : Overriden FreeInstance for singleton
* Returns : nothing
********************************************************************************}
procedure TuexDebugLogger.FreeInstance;
begin
Dec( debuggerRefCount );
if debuggerRefCount = 0 then
begin
inherited FreeInstance;
end;
end;
This appeared to be working, but now it isn't and we have several distinct instances, instead of 1 !
Has anyone got any ideas as to why it won't work anymore ?
http://edn.embarcadero.com/article/22576
I am not sure how that could have worked in the first place: where do you set the variable named debugger?
ReplyDeleteUwe Raabe Sorry missed off the constructor. There is a line towards the end that is ( at the moment ) commented out that assigns debugger ( debugger := Self; )
ReplyDelete{*****************************************************************************
* Class : TuexDebugLogger
* Function : Create
* Arguments : aApplication: The application name
* Action : Create the component and set defaults
* Works in conjunction with the overidden NewInstance and
* FreeInstance methods to create a singleton
* Returns : An object pointer
*******************************************************************************}
constructor TuexDebugLogger.Create( aApplication: string; location: TDebugFolder );
begin
if Assigned( debugger ) then
begin
Self := debugger;
end
else
begin
fApplicationName := StripExtension( ExtractFileName(aApplication) );
logPathName := IncludeTrailingPathDelimiter( debugger.BuildLogPath( location, aApplication ) );
logName := Format('%s%s_%s.log',[logPathName, fApplicationName, FormatDateTime( LOG_FILENAME_DATE, Now )] );
objQueue := TQueue.Create;
SetupTimer;
//debugger := Self;
end;
end;
Can you provide a small example to reproduce it?
ReplyDeletePut that in a separate unit with a test case around it that fails in Tokyo but succeeds in <= Berlin.
ReplyDeleteIt's alright guys! My mistake sorry I thought the code was actually assigning the debugger value, but it wasn't. I'll test my theory in the morning but I'm almost certain it will run. Thanks guys
ReplyDeleteI was wondering about the lack of critical sections and threading.
ReplyDeleteLars Fosdal Oh we have threading don't worry !! We are using PPL
ReplyDeleteAre you in control of which thread that first creates the debugger?
ReplyDeleteLars Fosdal That bit is not threaded, so yes !
ReplyDeleteGuys; it's all working again.... and working correctly as a threaded singleton debug logger .... life is good again ;-) ah ...... Thank you all for your help !!
ReplyDelete