Eeek! That looks like trouble.
First up, shouldnt this line be
while not MemTableQuery.EOF?
if not MemTableQuery.EOF then
ThreadRecords should not be a global array. Since each thread has its own TBufDataset, and only that thread should ever access its dataset, the object should be a strict private field inside the TThread class. The TBufDataset should be created by a thread, and freed when the thread finishes. Usually in the constructor/destructor.
Its unclear how you are transferring thread "seeding" data to the TBufDatasets, but I would look into a intermediate data structure.
So, pull record data from MemTableQuery and place it into a new record, pass that record to the thread constructor, which will then create a new TBufDataset and work in the background doing whatever it wants without having access to any _other_ data, other than what you have provided it.
Your list of threads should be stored in a TThreadList. Which is simply a thread safe TList to prevent multiple threads accessing the list at the same time. If you look in the following code:
fpcsrc/3.2.0/rtl/objpas/classes/classes.inc
You will find a private TThread class called TExternalThread. This gives a perfect example of how to use a TThreadList to safely manage multiple TThreads.
constructor TExternalThread.Create;
begin
FExternalThread := True;
{ the parameter is unimportant if FExternalThread is True }
inherited Create(False);
with ExternalThreads.LockList do
try
Add(Self);
finally
ExternalThreads.UnlockList;
end;
end;
destructor TExternalThread.Destroy;
begin
inherited;
if not ExternalThreadsCleanup then
with ExternalThreads.LockList do
try
Extract(Self);
finally
ExternalThreads.UnlockList;
end;
end;
Note how the thread adds and removes itself from a global TThreadList. Only then can you safely count how many threads are running, and iterate the threads to signal them to terminate.
Anyway, hope that helps.
EDIT: One last thought. Think about threads as external programs. Don't "cheat" and allow thread code access to your entire app. Isolate the thread code in its own unit, and only pass data to it that it needs. And lock those threads up in a TThreadList. Otherwise, it gets messy!