El 10/12/15 a les 11:13, Sven Barth ha escrit:
Show quoted text 30 lines
Am 10.12.2015 11:05 schrieb "Luca Olivetti" <
>:
>
> Hello,
>
> in a couple of programs I'm using this idiom:
>
>
> FMyThread:=TMyTread.Create;
> FMyThread.FreeOnTerminate:=false;
>
>
> procedure TMyForm.MyThreadTerminate(Sender:TObject);
> begin
> //do something with FMyThread then
> FreeAndNil(FMyThread);
> end;
>
>
> With fpc 2.6.4 it worked flawlessly, with fpc 3.0 sometimes it causes
a sigsev somewhere inside CheckSynchronize.
>
> I could find nothing here
>
http://wiki.freepascal.org/User_Changes_3.0
> related to this.
> I realize that's an implementation detail so probably what I did was
wrong (was it?).
I'd need to check what the RTL does after OnTerminate is called, but it
could be that this worked by chance...
Yes and no: OnTerminate is called via Synchronize. In 2.6.4 there could be only one outstanding synchronized method and CheckSynchronize wouldn't access the thread after calling it, so freeing the thread inside OnTerminate was no problem.
Now it's been changed to use a queue of waiting methods, and CheckSynchronize, after calling the method, calls
RtlEnventSetEvent(tmpentry^.SyncEvent)
where SyncEvent is a member of the thread, and if the thread has already been freed that's going to bomb.
It's obvious that you cannot free the thread from inside a "normal" Synchronize call, it's no so obvious you cannot do it in the OnTerminate method, so maybe a note could be added in
http://wiki.freepascal.org/User_Changes_3.0
The new implementation is clearly better....once you know *not* to free the thread inside OnTerminate.
Bye
Luca