I have a class in which i start a thread.
In some cases this class gets destroyed very soon (before Thread finishes).
Therefore i tried to use a CriticaSection to wait in the destructor for the thread to finish:
Thread:
procedure TSVNReader.Execute;
begin
DebugLn(' SVNReader start %s/%s', [fKISFile.Lib.Name, fKISFile.Name]);
try
fKISFile.ThreadReadSVN;
finally
DebugLn(' SVNReader stop %d/%s', [fKISFile.Lib.Name, fKISFile.Name]);
fKISFile.UnlockSVNReader;
end;
end;
Class constructor:
constructor TprimeKISFile.Create(...);
begin
InitCriticalSection(fSVNReaderCriticalSection);
inherited Create(...);
...
LockSVNReader; // gets unlocked in the end of the threads execute method
try
DebugLn(' creating SVNReader %s/%s', [fLib.Name, fName]);
TSVNReader.Create(Self);
except
UnlockSVNReader;
DebugLn('TSVNReader.Create(%s) failed in Create()', [AFileName]);
end;
...
end;
Class destructor:
destructor TprimeKISFile.Destroy;
begin
LockSVNReader;
DebugLn('Destroy %s/%s', [fLib.Name, fName]);
...
UnlockSVNReader;
DoneCriticalsection(fSVNReaderCriticalSection);
inherited Destroy;
end;
Lock & Unlock:
procedure TprimeKISFile.LockSVNReader;
begin
EnterCriticalsection(fSVNReaderCriticalSection);
DebugLn('%s/%s SVNReader locked', [fLib.Name, fName]);
end;
procedure TprimeKISFile.UnlockSVNReader;
begin
DebugLn('%s/%s SVNReader unlocked', [fLib.Name, fName]);
LeaveCriticalsection(fSVNReaderCriticalSection);
end;
I've also use a thread save DebugLn:
procedure DebugLn(const S: String; Args: array of const);
begin
EnterCriticalsection(fLock);
try
//WriteLn(fLog, Format(S, Args));
DebugLogger.DebugLn(S, Args);
finally
LeaveCriticalsection(fLock);
end;
end;
when i run my prog it outputs:
t189/SSCX120.CBL SVNReader locked
creating SVNReader t189/SSCX120.CBL
SVNReader start t189/SSCX120.CBL
ThreadReaderSVN t189/SSCX120.CBL
t189/SSCX120.CBL SVNReader locked
Destroy t189/SSCX120.CBL
t189/SSCX120.CBL SVNReader unlocked
d211/SSCX120.CBL SVNReader locked
creating SVNReader d211/SSCX120.CBL
SVNReader start d211/SSCX120.CBL
ThreadReaderSVN d211/SSCX120.CBL
d211/SSCX120.CBL SVNReader locked
Destroy d211/SSCX120.CBL
d211/SSCX120.CBL SVNReader unlocked
h054/SSCX120.CBL SVNReader locked
creating SVNReader h054/SSCX120.CBL
SVNReader start h054/SSCX120.CBL
ThreadReaderSVN h054/SSCX120.CBL
-> access violation here due to access of the first threads execute method to the destroyed object
It looks like the critical section has no effect. Output should look like this:
t189/SSCX120.CBL SVNReader locked
creating SVNReader t189/SSCX120.CBL
SVNReader start t189/SSCX120.CBL
ThreadReaderSVN t189/SSCX120.CBL
SVNReader stop t189/SSCX120.CBL ***
t189/SSCX120.CBL SVNReader unlocked ***
t189/SSCX120.CBL SVNReader locked
Destroy t189/SSCX120.CBL
What am i doing wrong?