Impovement suggestion

Giganews Newsgroups
Subject: Impovement suggestion
Posted by:  Igor Panchenko (ig…@implabs.com)
Date: Mon, 18 Sep 2006

I'm using Indy9 but the idea applies to Indy10 too.

IdIOHandlerSocket.pas:

procedure TIdIOHandlerSocket.ConnectClient(...

  procedure ConnectTimeout(ATimeout: Integer);
  begin
    ...
    with TIdConnectThread.Create(True) do try
      FBinding := Binding;
      Resume;
      // Sleep
      if TIdAntiFreezeBase.ShouldUse then begin
        LSleepTime := Min(GAntiFreeze.IdleTimeOut, 125);
      end else begin
        LSleepTime := 125;
      end;

      if LInfinite then begin
        ATimeout := LSleepTime + 1;
      end;

      while ATimeout > LSleepTime do begin
        IdGlobal.Sleep(LSleepTime);
        ATimeout := ATimeout - LSleepTime;

        if LInfinite then begin
          ATimeout := LSleepTime + 1;
        end;

        TIdAntiFreezeBase.DoProcess;
        if Terminated then begin
          ATimeout := 0;
          Break;
        end;
      end;
      IdGlobal.Sleep(ATimeout);
      ...
  end;

begin
  ...
  if (ATimeout = IdTimeoutDefault) or (ATimeout = 0) then begin
    if TIdAntiFreezeBase.ShouldUse then begin
      ConnectTimeout(120000); // 2 Min
    end else begin
      GStack.CheckForSocketError(Binding.Connect);
    end;
  end else begin
    ConnectTimeout(ATimeout);
  end;
  ...
end;

The problem with this code is that connection attempt will take at least
125 milliseconds in some cases (or in most cases, depending on what are
you doing).
This is because IdGlobal.Sleep(LSleepTime) is always called before checking
Terminated property of the ConnectThread.
125 ms per connect is unacceptable for some kind of applications that need
to make
many connections fast, such as webbrowsers or proxies for example. And why
have to wait with Sleep() at all if the connection was established quickly?
I suggest to change IdGlobal.Sleep(LSleepTime) to
WaitForSingleObject(Handle, LSleepTime)
and add Windows to the uses clause.
Like this:

{$IFDEF LINUX}
IdGlobal.Sleep(LSleepTime);
{$ENDIF}
{$IFDEF MSWINDOWS}
WaitForSingleObject(Handle, LSleepTime);
{$ENDIF}

Or maybe move WaitForSingleObject() to IdGlobal and call it from there?

p.s.
  I've tested this code and it works just fine.

Replies