Board index » delphi » Indy 9.0.18 TidTelnet - in case you didn't know...

Indy 9.0.18 TidTelnet - in case you didn't know...


2005-02-13 04:53:31 PM
delphi167
When a server performs a managed disconnect, TidTelnet now notices and fires
the onDisconnected event. This is more than happened with 9.0.14, where you
had to trap the exception from the read thread to detect
EconnClosedGracefully & post a message to have the main thread call
disconnect.
With 9.0.18, however, after a server-disconnect the internal 'connected'
state is set to false but, unfortunately, the read thread is not shut down.
Sunsequent attempts to close the app will fail because of the
'waitAllTerminated' finalization in TidThread.
Also, one thread leaks every time this happens. After three successuful
connects and three server disconnects, the GThreadCount in the
waitAllTerminated is up to three.
Once one thread has leaked, the app will not shut down no matter what
happens. The use can click on their 'Disconnect' button & call disconnect
as many times as they want but only the current read thread is terminated if
it is flagged as connected. The leaked thread/s still lurk around in the
GThreadLock lockList to stop your app closedown dead.
The workaround is to always call 'disconnect' when 'disconnected' and ignore
any connected' state, because it lies. ie
'if myTelnet.connected then myTelnet.disconnect;'
which is what users tend to code up in onClose handlers and the like, will
lead to app close fails.
Rgds,
Martin
PS Indy 10 TidTelnet is still unuseable, as of yesterday, because of the
100% CPU bug.
PPs why is 'Telnet' so esy to mis-type as 'Telent'?
 
 

Re:Indy 9.0.18 TidTelnet - in case you didn't know...

"Martin James" <XXXX@XXXXX.COM>writes
Quote
With 9.0.18, however, after a server-disconnect the internal
'connected' state is set to false but, unfortunately, the read thread
is not shut down. Sunsequent attempts to close the app will fail
because of the 'waitAllTerminated' finalization in TidThread.
You must not be using the latest version, because there is no such
finalization in the current snapshot version. Please always try using the
latest snapshot before reporting problems, as they may have already been
addressed.
Quote
PS Indy 10 TidTelnet is still unuseable, as of yesterday, because
of the 100% CPU bug.
What are you talking about?
Gambit
 

Re:Indy 9.0.18 TidTelnet - in case you didn't know...

Quote

You must not be using the latest version, because there is no such
finalization in the current snapshot version. Please always try using the
latest snapshot before reporting problems, as they may have already been
addressed.
OK, I will download the snapshot & I will see.
Quote
>PS Indy 10 TidTelnet is still unuseable, as of yesterday, because
>of the 100% CPU bug.

What are you talking about?
Telnet app. After a successful connection:
9.0.14: CPU use 0%
9.0.18 CPU use 0%
10.0.52: CPU use 100%
10.0.yesterdaySnapshot: CPU use 100%
In idIOHandlerStack, I changed:
**************************************
function TIdIOHandlerStack.Connected: Boolean;
begin
ReadFromSource(False, 0, False);
Result := inherited Connected;
end;
**************************************
to:
**************************************
function TIdIOHandlerStack.Connected: Boolean;
begin
ReadFromSource(False, 20, False);
Result := inherited Connected;
end;
**************************************
to prevent endless looping.
For some reason, if the zero timeout is set & the app pused, the loop seems
to be around calls to Tapplication.handleMessage. I do not know where this
call is in the source code. Setting the bodge-timeout to 20 stops the 100%
CPU use, but I am sure this is grossly unsatisfactory. Unfortunately,
despite the use of a read thread, setting the timeout to 'INFINITE', which
would seem 'normal', prevents any data being fired at all :(
Rgds
Martin
 

Re:Indy 9.0.18 TidTelnet - in case you didn't know...

Quote
>
>You must not be using the latest version, because there is no such
>finalization in the current snapshot version. Please always try using
the
>latest snapshot before reporting problems, as they may have already been
>addressed.

OK, I will download the snapshot & I will see.

Just downloaded the Indy 9 snapshot zip from the fulgar server, (theUK
mirror seems to be down).
First past, and last part of TidThread, showing the last revision and the
initialization/finalization sections:
{ $HDR$}
{**********************************************************************}
{ Unit archived using Team Coherence }
{ Team Coherence is Copyright 2002 by Quality Software Components }
{ }
{ For further information / comments, visit our WEB site at }
{ www.TeamCoherence.com }
{**********************************************************************}
{}
{ $Log: 10375: IdThread.pas
{
{ Rev 1.3 12.9.2003 ? 16:37:08 DBondzhev
{ Fixed AV when exception is raised in BeforeRun and thread is terminated
{ before Start is compleated
..
..
..
..
procedure TIdBaseThread.Synchronize(Method: TMethod);
Begin
inherited Synchronize(TThreadMethod(Method));
End;//
initialization
finalization
WaitAllTerminated;
end.
 

Re:Indy 9.0.18 TidTelnet - in case you didn't know...

"Martin James" <XXXX@XXXXX.COM>writes
Quote
10.0.52: CPU use 100%
10.0.yesterdaySnapshot: CPU use 100%
The only way for that to happen is if a tight unyielding loop is occuring.
Quote
In idIOHandlerStack, I changed:
<snip>
You should not have done that. Connected() is supposed to return
immediately, not after a 20ms delay.
Quote
For some reason, if the zero timeout is set & the app pused,
the loop seems to be around calls to Tapplication.handleMessage.
There is no call to HandleMessage(). The only thing in the entire Indy
library that calls TApplication.ProcessMessages() is TIdAntiFreeze, and it
is only allowed to be used in the context of the main VCL thread. All Indy
code that deals with TIdAntiFreeze is disabled when called in the context of
worker threads.
Quote
Setting the bodge-timeout to 20 stops the 100% CPU use, but
I'm sure this is grossly unsatisfactory.
You are looking in the wrong place. A better fix would probably be as
follows instead:
procedure TIdTelnetReadThread.Run;
begin
//...
// FClient.IOHandler.CheckForDataOnSource;
FClient.IOHandler.CheckForDataOnSource(20);
if not FClient.IOHandler.InputBufferIsEmpty then begin // <-- add
this
if FClient.ThreadedEvent then begin
HandleIncomingData;
end else begin
Synchronize(HandleIncomingData);
end;
end; // <-- add this
FClient.IOHandler.CheckForDisconnect;
end;
Gambit
 

Re:Indy 9.0.18 TidTelnet - in case you didn't know...

..but, on the bright side, wit hthe snapshot verson, 'connected' now returns
'false' after a server disconnect and the read thread is terminated - it is
not necessary to call 'disconnect' after a server-side
'EidCOnnClosedGracefully' disconnection. I will keep the disconnect in, but
only just in case I have to go back - it is not necessary.
Thanks,
Martin