[fpc-devel] TThread.Queue and TThread.Destroy

Sven Barth pascaldragon at googlemail.com
Thu Jun 21 21:21:50 CEST 2018


Am 21.06.2018 um 10:26 schrieb Martin:
> On 21/06/2018 01:27, Martin wrote:
>> fpc 3.0.4 / Linux 64bit (Fedora)
>>
>> What should happen if:
>>
>> - A Thread has queued a call with "TThread.Queue"
>> - The Thread gets Terminated and Destroyed before the queued method 
>> can be executed.
>>   That is the thread checks for "Terminated" and exits Execute before 
>> the queued method can be executed.
>>
>> Diving into TThread.Destroy I can see: RemoveQueuedEvents(Self);
>> So I would assume that all the queued calls are removed, and will not 
>> be executed.
> ...
>>
>> class procedure TThread.RemoveQueuedEvents(aThread: TThread; aMethod: 
>> TThreadMethod);
>> var
>>   entry, tmpentry, lastentry: PThreadQueueEntry;
>> begin
>>   { anything to do at all? }
>>   if not Assigned(aThread) or not Assigned(aMethod) then
>>     Exit;
> Arrgh, my fault, the above is correct, but instead a few lines further
>
>       if Assigned(aThread) and (entry^.Thread <> aThread) then begin
>         lastentry := entry;
>         entry := entry^.Next;
>         Continue;
>       end;
>       { then check for the method }
>       if entry^.Method <> aMethod then begin  ///////////// <<< should 
> that not also be "if assigned(aMethod) and ..." // entry^.Method will 
> never be equal to nil
>         lastentry := entry;
>         entry := entry^.Next;
>         Continue;
>       end;

Would you please test with trunk? There it already checks for aMethod.

Also at least on x86_64-win64 your example works correctly, though that 
you're calling foo.Destroy directly after foo.Terminate is potentially 
dangerous: depending on the current system load the thread instance 
might be freed before the thread has fully finished executing (there is 
a bit of cleanup stuff happening after the thread returns from Execute). 
So the safest is to call foo.WaitFor before calling foo.Destroy and in 
that case WaitFor will call CheckSynchronize until the thread really 
finished (at least on Windows, OS/2 and Unix-like) as OnTerminate (if 
assigned) is called using Synchronize.

Regards,
Sven



More information about the fpc-devel mailing list