El 10/12/15 a les 11:13, Sven Barth ha escrit:
Am 10.12.2015 11:05 schrieb "Luca Olivetti" <l...@ventoso.org
<mailto:l...@ventoso.org>>:
 >
 > Hello,
 >
 > in a couple of programs I'm using this idiom:
 >
 >
 > FMyThread:=TMyTread.Create;
 > FMyThread.FreeOnTerminate:=false;
 > FMyThread.OnTerminate:=@MyThreadTerminate
 >
 > 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
_______________________________________________
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Reply via email to