We have a Indy (version 10.6.1.5235) TIdHttpServer "service" that has worked well for years with Delphi 2007. After the most recent Windows Update (KB4338815 and KB4338830) we noticed the service freezes when TIdHttpServer is set to false.
I have included source code where TIdHttpServer is created. In our service "Stop" handler we set IdHttpServer1.Active to False and this is where it freezes. It seems Indy hangs when it is trying to close the http connections. Is there a work around?
Update One Per Remy Lebeau, I have created a Minimal, Complete, and Verifiable example. Here it is:
procedure TMainForm.Button1Click(Sender: TObject);
begin
memo1.clear;
iCall := 0;
IdHTTPServer1 := TIdHTTPServer.Create;
IdHTTPServer1.MaxConnections := 10;
IdHTTPServer1.AutoStartSession := True;
IdHTTPServer1.SessionState := True;
IdHTTPServer1.OnCommandGet := IdHTTPServer1CommandGet;
IdHTTPServer1.KeepAlive := False;
idHttpServer1.DefaultPort := 80;
if ReuseSocket.checked then
IDHTTPSERVER1.ReuseSocket := rsTrue;
IdHTTPServer1.Active := True;
end;
procedure TMainForm.IdHTTPServer1CommandGet(AContext: TIdContext;
ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
begin
iCall := iCall + 1;
if iCall mod 100 = 0 then
memo1.lines.add(inttostr(iCall)+ ' calls made');
AResponseInfo.ContentText := '<html><body>Hello There</body></html';
end;
procedure TMainForm.StopClick(Sender: TObject);
begin
try
IdHTTPServer1.Active := False;
memo1.lines.add('IdHTTPServer1.Active := False;');
except
on e: exception do
memo1.lines.add('Exception on IdHTTPServer1.Active := False; Message:'+e.message);
end;
end;
Application will run fine but once you click the "Stop" button which sets the IdHttpServer Active property to False it hangs.
OnCommandGetevent handler is not thread-safe.TIdHTTPServeris a multi-threaded component, its events are fired in the context of internal worker threads, so you MUST sync with the main UI thread when accessing theTMemocomponent on your Form, or else bad things happen. I suggest you useTThread.Queue()orTIdNotifyfor that, so the server does not have to wait on the sync to complete. - Remy LebeauTCriticalSectionwill not fix that (though you can use it to provide safe access to youriCallvariable, at least, though considerTIdThreadSafeIntegerinstead). Indy servers automatically disconnect active clients for you during deactivation. The freeze occurs when Indy waits for those client threads to terminate, which they won't if your event handlers cause deadlocks (and accessing a UI component from outside the UI thread can deadlock). - Remy Lebeau