My idea is to use TDictionary to manage client connections on IdTCPServer. Here is a simple example code (not tested) for understanding purposes:
var
Dic: TDictionary<string, TIdContext>;
procedure TfrmMain.FormCreate(Sender: TObject);
begin
Dic := TDictionary<string, TIdContext>.Create;
end;
procedure TfrmMain.FormDestroy(Sender: TObject);
begin
Dic.Free;
end;
procedure TfrmMain.TCPServerConnect(AContext: TIdContext);
var
Hostname: string;
begin
Hostname := UpperCase(GStack.HostByAddress(AContext.Binding.PeerIP));
if not Dic.ContainsKey(Hostname) then Dic.Add(Hostname, AContext);
end;
procedure TfrmMain.TCPServerDisconnect(AContext: TIdContext);
var
Hostname: string;
begin
Hostname := UpperCase(GStack.HostByAddress(AContext.Binding.PeerIP));
if Dic.ContainsKey(Hostname) then
begin
Dic[Hostname].Free;
Dic.Remove(Hostname);
end;
end;
Is this code thread safe?
In a word: No.
If you inspect the source of TDictionary you should quickly realise that there is no provision for thread-safety in the implementation itself. Even if it were, by having discrete calls to a Dic instance you have potential race conditions to contend with:
if Dic.ContainsKey(Hostname) then
begin
// In theory the Hostname key may be removed by another thread before you
// get a chance to do this : ...
Dic[Hostname].Free;
Dic.Remove(Hostname);
end;
You need to make your own use of Dic thread safe, and fortunately in this sort of example this is easily achieved using a monitor on the object itself:
MonitorEnter(Dic);
try
if not Dic.ContainsKey(Hostname) then
Dic.Add(Hostname, AContext);
finally
MonitorExit(Dic);
end;
// ....
MonitorEnter(Dic);
try
if Dic.ContainsKey(Hostname) then
begin
Dic[Hostname].Free;
Dic.Remove(Hostname);
end;
finally
MonitorExit(Dic);
end;
If you are not familiar with monitors in Delphi, in simple terms you can think of a monitor as a ready-to-use critical section supported by every TObject descendant (in older versions of Delphi which did not support these monitors you could have achieved the same thing with an explicit critical section).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With