I have a TThreadList wich holds all pointers to objects created by my server. The server has a pool of threads to send data to all clients in that thread list. It locks the list and then releases the list after a user disconnects, removing the object and reference pointer.
Problem is: with the pool of threads that does not know when a socket is disconnected and deleted, so when the pool works, it will AV on selected pointer from the thread list that is somehow already deleted.
Example, pool’s Execute method:
try
with userlist.LockList do
begin
for i := Count - 1 downto 0 do
begin
if i >= 0 then
begin
p := TClient(items[i]);
//problem here p gets deleted so it raises items[i]
//have an invalid pointer to memory
if p <> nil then
if p.sockethex <> nil then
begin
sendtexthexpool(p.sockethex, msgprimit+ '|'); //here AV cause P was deleted
end;
end;
end;
end;
finally
userlist.UnlockList;
end;
end;
If all you have is a pointer, there’s no way for you to tell whether or not it has been freed. You have to get your program to keep track of this information.
Even if you could detect a stale pointer, which you can’t, it would not help you. You would still have a race.
In your excerpt you have a thread list. So long as all access to the pointer is made whilst the list is locked then you will have no problems. Presumably you are freeing the object whilst not holding a lock to the list. Fix that problem and all should be well.