[fpc-pascal] TThread.FreeOnTerminate

Martin Frb lazarus at mfriebe.de
Fri Dec 14 11:16:36 CET 2018


On 14/12/2018 10:30, Michael Van Canneyt wrote:
>> (or as Martin says, it should be documented as such?)
>
> This is a valid point and I intend to elaborate the TThread documentation
> somewhat, with this in mind.

I did have an error in my initial example:
>    t := TThread.create(false); // create  not suspended
>    // do something
>    if foo then begin // decide we do not need the result
>      t.FreeOnTerminate:= true;
>      t.terminate;
>   end;
Obviously "t.terminate" is not save after "t.FreeOnTerminate:= true; " 
because by that time t may be dangling. The only thing save to do with 
"t" after at that point is "t:=nil".

But that aside, I think there are 2 thinks that can be made part of the 
documentation (they may be obvious, but "obvious" here is a relative 
term, depending on the readers experience)

1)
A thread that has its FreeOnTerminate property set to "True" must not be 
accessed in any for by any other thread.

An exception to this rule, is access to the thread from inside a 
synchronize event, that comes from the very thread itself. This is 
because the while the synchronize event is executed the thread is on 
hold and can not be destroyed.

[optional]
This is also true for any thread that at any time had its 
FreeOnTerminate property set to "True", and then reverted it back to 
false (from within the thread itself, as this the thread itself is the 
only place that is still allowed access).
Again the exception is that the property can be reverted inside a 
synchronize event, in which case the thread can be accessed again after 
that.

2)
The FreeOnTerminate property is evaluated once the thread's Execute 
method is exited. This is *before* "procedure DoTerminate; virtual;" and 
the "OnTerminate: TNotifyEvent" are executed. [[According to 
google/stackoverflow, this is the same in Delphi]]

Document relation to property "Finished" / see below

----
For (2) I have a question/request

The current FPC implementation (3.0.4) is
     FreeThread := Thread.FFreeOnTerminate;  // property is evaluated / 
can no longer be changed
     Result := Thread.FReturnValue;
     Thread.FFinished := True;  // Marked as finished
     Thread.DoTerminate;
     if FreeThread then
       Thread.Free;

Could "Thread.FFinished := True;"  be moved to the top? (potentially 
together with   "Result := Thread.FReturnValue;" so the order of those 2 
remains).

The reason is, that then (on a suspended thread) it would be save to 
change "FreeOnTerminate" if "Finished = False".

This should be ok, the doc 
https://www.freepascal.org/docs-html/rtl/classes/tthread.finished.html 
explicitly states that when it is true "the thread is still cleaning up 
(calling OnTerminate, etc)."


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freepascal.org/pipermail/fpc-pascal/attachments/20181214/0628b693/attachment.html>


More information about the fpc-pascal mailing list