[fpc-pascal] Does TThread.Execute terminate thread on exit?

Bo Berglund bo.berglund at gmail.com
Sun Nov 1 19:39:19 CET 2015


On Sun, 01 Nov 2015 17:25:55 +0000, Mark Morgan Lloyd
<markMLl.fpc-pascal at telemetry.co.uk> wrote:

>Tobias Giesen wrote:
>> Yes it will terminate and free (if FreeOnTerminate is true).
>
>Remember that if it frees itself due to falling out of the Execute() 
>procedure, a variable containing the TThread descendant won't be set nil.
>
>On the other hand, if it doesn't free itself and relies on the main 
>thread checking an "executing" flag, there's a race condition between 
>this being reset and its being safe for the main thread to call 
>FreeAndNil().

Hi Mark, you know about my project from the Lazarus list...
But for others:
I am trying to make a TCPIP communications class based on the Indy
TIdTCPClient class. It will replace a serial communications object in
an existing quite big class.
But to do that I need the TCP receive data handling to be event based
so Remy Lebeau adviced to use a thread to handle the receiving and
fire off an event when data arrives.

So I have (with his help) created a descendant of the TThread class
that contains an Execute method that loops a blocking Read function
with a timeout plus a few other things. If there are data received
these will be supplied to an OnRead event function (via Synchronize)
from the thread to the main application.

Now, where should the TIdTCPClient be located? The first suggestion
was in the TThread decendant, but when I wanted to also add the Write
function (obviously) I was adviced to move it outside the read thread
and supply it as a parameter in the constructor instead. And the
thread could then be created in the OnConnect event fired in the
context of the main thread when a connection is made.

Now my concern is how to disconnect the TCP connection safely from the
main thread? The read thread may well be in the blocking call to Read
when this happens....
So I figured I could simply move the disconnect functionality over to
the read thread where a call to Disconnect would set a flag which is
acted on in the Execute loop.

So if the flag is set then the execute function should disconnect the
client and then what?

Exit the Execute loop?
As explained to me here this will free the thread...
Or move on in Execute to a loop only checking Terminated and exit when
Terminated is true?

I guess that the second way would be the best, since then the main
thread retains the responsibility to terminate and free the thread
after first commanding Disconnect (and gotten feedback from the
OnDisconnect event).....

Any other suggestions?
Threading is tricky business...


-- 
Bo Berglund
Developer in Sweden




More information about the fpc-pascal mailing list