Well my pascal might not be that good, but to me it looks like that, only the method is attached to the queue. Not the call, the method to be called, is marked with the thread and is placed in the list.
Correct.
Well alarm bell No 1. If the thread that is queuing a method is the main thread the method is executed on the spot and never queued. That is a huge bug. The only reason one will queue a method from the main thread is to be executed on a later time, after the current process has finished and the code forces it to be executed now. Wow!!
It is not actually a bug, just a design limitation. TThread.Queue() was originally designed to follow the same semantics as TThread.Synchronize() (or even Windows, for that matter). If the main thread calls TThread.Synchronize() or TThread.Queue() (or SendMessage()), the requested method (or message handler) is executed right away. Only methods (or messages) requested (sent) by a worker thread are queued for execution in the main thread when it finds time to execute them.
For the record, the ability to have the main thread queue a delay-executed method was recently added to Delphi in 10.2 Tokyo, with the introduction of the
TThread.ForceQueue() method. FreePascal does not have an equivalent yet. A close approximation would be to have the main thread use TThread.CreateAnonymousThread() to call TThread.Queue() (the same was true in Delphi until ForceQueue() was added).
the code first locks access to the thread with a critical section then uses the variable ThreadQueueTail that is not declared in the procedure it self to append the queued method to what it looks like a single linked list.
Yes, it is a global thread-safe list owned by the RTL, not TThread itself. The main thread calls
CheckSynchronize() periodically to execute pending methods that are waiting in the list.
hmm the only way this could be thread bound is if the variables threadQueueHead and ThreadQueueTails are some how re declared for each thread the only construct that I know of that can do that is a threadvar
They are not threadvars. Just simple globals, protected by the critical section.
It looks like a single list for all threads to me,l as expected.
Correct.
So the main question now is why does the list needs to know which thread added which method to the list so I looked at the checkSynchronise procedure and found nothing that uses that information.
It doesn't care which thread is *adding* an item to the list. It only cares which thread is *associated* with an item. For instance, a queued method might need to access members of its associated thread object, so associating the method with a thread object ensures that thread object is still valid when the method is called.
So there mast be something else that uses it and after a bit of searching I found a couple of methods that use that information and guess what they are all methods of TThread that remove methods from the queue.
I quess that is helpfull, there might be a reason you want a previously queue method not to be executed
If the queued method accesses its associated thread object, and the thread object is destroyed before the queued method is called, the method has to be removed from the list to avoid crashing.
Now knowing that the queue method has no role what so ever in the list after it finishes executing, knowing that the queued method might be anything from any class or worst no class, knowing that the only peace of code that checks who added the method in the queue is in TThread it self, can some one please explain to me what is this suppose to protect?
See above, and my earlier reply, too.