CallAction in "lnet" discards milliseconds in timeout (easy fix)
Original Reporter info from Mantis: dezlov
-
Reporter name: Denis Kozlov
Original Reporter info from Mantis: dezlov
- Reporter name: Denis Kozlov
Description:
TLSelectEventer.CallAction is called when user needs to wait for events on socket. TLSelectEventer also contains Timeout property which defines how much time in milliseconds to spend waiting in the CallAction method, ultimately in fpSelect function.
Internaly, Timeout variable is of type TTimeVal (record tv_sec, tv_usec: Longint). When user sets the Timeout property the supplied value is getting broken down into tv_sec and tv_usec components. Unfortunately, this break down process (as well as gluing it back together) is performed incorrectly.
Also, CallAction should check that both tv_sec and tv_usec components a larger or equal to zero before passing timeout to fpSelect.
P.S. Using latest available lnet 0.6.5
Steps to reproduce:
Test code:
---------------------------------
program project;
{$mode objfpc}{$H+}
uses
SysUtils, lnet;
var
I: Integer;
tcp: TLTcp;
begin
tcp := TLTcp.Create(nil);
tcp.Timeout := 500; // 500 ms wait time!
tcp.Listen(12345);
for I := 1 to 10 do
begin
WriteLn(FormatDateTime('SS.ZZZ', Now));
tcp.CallAction;
end;
ReadLn;
end.
---------------------------------
Output when using original levents.pp:
---------------------------------
44.375
44.390
44.406
44.421
44.437
44.453
44.468
44.484
44.500
44.515
---------------------------------
As you see, there is no 500 ms waiting time in the output above.
Output when using patched/fixed levents.pp:
---------------------------------
48.484
49.000
49.500
50.000
50.500
51.000
51.500
52.015
52.515
53.015
---------------------------------
You can clearly see a 500 ms waiting time.
Additional information:
Patch to fix problem in levents.pp:
---------------------------------
512c512
< Result := (FTimeout.tv_sec * 1000) + FTimeout.tv_usec;
---
Result := (FTimeout.tv_sec * 1000) + (FTimeout.tv_usec div 1000);<br/>
519c519
< FTimeout.tv_usec := Value mod 1000;
---
FTimeout.tv_usec := (Value mod 1000) * 1000;<br/>
574c574
< if FTimeout.tv_sec >= 0 then
---
if (FTimeout.tv_sec >= 0) and (FTimeout.tv_usec >= 0) then
---------------------------------
Mantis conversion info:
- Mantis ID: 20556
- OS: All
- OS Build: All
- Build: All
- Platform: All
- Fixed in revision: 2585 (#812a8167)
- Monitored by: » dezlov (Denis Kozlov)