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

Comments

  1. I am not sure how that could have worked in the first place: where do you set the variable named debugger?

    ReplyDelete
  2. Uwe 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; )


    {*****************************************************************************
    * 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;

    ReplyDelete
  3. Can you provide a small example to reproduce it?

    ReplyDelete
  4. Put that in a separate unit with a test case around it that fails in Tokyo but succeeds in <= Berlin.

    ReplyDelete
  5. It'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

    ReplyDelete
  6. I was wondering about the lack of critical sections and threading.

    ReplyDelete
  7. Lars Fosdal Oh we have threading don't worry !! We are using PPL

    ReplyDelete
  8. Are you in control of which thread that first creates the debugger?

    ReplyDelete
  9. Lars Fosdal That bit is not threaded, so yes !

    ReplyDelete
  10. Guys; 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

Post a Comment