2

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.

M Schenkel
  • 6,294
  • 12
  • 62
  • 107
  • Can you try a newer version of Indy? (10.6.1 is rather old) – mjn42 Jul 16 '18 at 13:44
  • Yes. downloaded Indy Version10.6.2.5464 and will let you know results. Is this the latest version of Indy? Sidenote: is there a place on indyproject.org to download? I found http://www.indyproject.org/Sockets/Download/Files/Indy10.EN.aspx but there does not seem to be source download. I ended getting it from https://indy.fulgan.com/ Is this the official repository for downloading? – M Schenkel Jul 16 '18 at 13:49
  • indy.fulgan.com is for nightly snapshots, but you can also checkout the source code directly from the [subversion repository](http://www.indyproject.org/Sockets/Download/svn.EN.aspx), see also https://indy.fulgan.com/Getting%20the%20latest%20Indy%2010%20snapshot%20using%20Tortoise%20SVN.pdf – mjn42 Jul 16 '18 at 13:58
  • @mjn42 - version 10.6.2.5464 did not make a difference. It still freezes when setting Active to False. – M Schenkel Jul 16 '18 at 14:43
  • @MSchenkel see http://www.indyproject.org/Sockets/Docs/Indy10Installation.EN.aspx for download links. As for the freeze, there is no way to diagnose that without seeing your code. The only way the deactivation can freeze is if the internal threads are deadlocking, such as if your event handlers are syncing with the same thread that is deactivating the server, for instance. Please show your actual code. – Remy Lebeau Jul 16 '18 at 16:10
  • @RemyLebeau I added a complete project. I also included the Windows Updates that prompted the problem. – M Schenkel Jul 16 '18 at 19:03
  • 3
    @MSchenkel you did not say whether there are any active client connections at the time you deactivate the server. However, your `OnCommandGet` event handler is not thread-safe. `TIdHTTPServer` is 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 the `TMemo` component on your Form, or else bad things happen. I suggest you use `TThread.Queue()` or `TIdNotify` for that, so the server does not have to wait on the sync to complete. – Remy Lebeau Jul 16 '18 at 19:29
  • @RemyLebeau - thanks... I understand writing to the TMemo is not Threadsafe. This was a quick example I put together. Had I wrapped that in a TCriticalSection would that have solved the issue? In any event I am suspect it not being ThreadSafe is not the issue here. To answer you question Yes I do believe there are active client connections. How to I force all clients to disconnect? – M Schenkel Jul 16 '18 at 19:36
  • 3
    @MSchenkel even simple tests can cause BIG problems if written incorrectly. NEVER access a UI component from outside of the UI thread. And NO, a `TCriticalSection` will not fix that (though you can use it to provide safe access to your `iCall` variable, at least, though consider `TIdThreadSafeInteger` instead). 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 Jul 16 '18 at 20:04

1 Answers1

4

You might have encountered this similar issue:

Windows 2012 R2 closesocket() hangs on listening socket

The issue was brought by patch from Microsoft KB4338815, which caused closesocket tо hang forever on Intel Xeon processors

That issue was fixed by uninstalling KB4338815, which you do have installed. So try uninstalling that KB on your system and see if it solves your issue.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • 2
    Yep... After we removed the update things work fine. – M Schenkel Jul 17 '18 at 02:43
  • 2
    See my answer in https://stackoverflow.com/questions/51372116/freezing-winsock-application-after-kb4338830-update/51387161#51387161 for Microsoft's patch for it – CSakura Jul 17 '18 at 17:28