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)."


_______________________________________________
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Reply via email to