end;\r
\r
\r
+{\r
+select in linux/sysV subtracts from timeout for time spent in it, but in BSD it doesn't\r
+enabling select_no_autotv here makes doSelect mimic the decrement behavior, in case the caller needs it\r
+the caller here in lcoreselect does not need it, and enabling it would have a slight perf hit.\r
+it is safe for this to be enabled even if the OS does it too (it will not subtract twice)\r
+it is currently disabled but can be enabled if needed\r
+}\r
+{$ifndef linux}{-$define select_no_autotv}{$endif}\r
+\r
Function doSelect(timeOut:PTimeVal):longint;//inline;\r
var\r
localtimeval : ttimeval;\r
maxslocal : integer;\r
+ {$ifdef select_no_autotv}\r
+ timeoutcopy,tvstart,tvend : ttimeval;\r
+ {$endif}\r
begin\r
//unblock signals\r
//zeromemory(@sset,sizeof(sset));\r
{$ifndef nosignal}\r
sigprocmask(SIG_UNBLOCK,@blockset,nil);\r
{$endif}\r
+\r
+ {$ifdef select_no_autotv}\r
+ if assigned(timeout) then begin\r
+ timeoutcopy.tv_sec := timeOut.tv_sec;\r
+ timeoutcopy.tv_usec := timeOut.tv_usec;\r
+ gettimemonotonic(tvstart);\r
+ end;\r
+ {$endif}\r
+\r
result := select(maxslocal+1,@FDSR,@FDSW,nil,timeout);\r
if result <= 0 then begin\r
fd_zero(FDSR);\r
end else begin\r
raise esocketexception.create('select returned error '+inttostr(linuxerror));\r
end;\r
+ end\r
+ {$ifdef select_no_autotv}\r
+ else if (result = 0) and assigned(timeout) then begin\r
+ //timeout reached: zero the timeval\r
+ timeout.tv_sec := 0;\r
+ timeout.tv_usec := 0;\r
end;\r
+ end else if assigned(timeout) then begin\r
+ //successful result: subtract elapsed time\r
+ gettimemonotonic(tvend);\r
+ tv_subtract(tvend,tvstart);\r
+ tv_subtract(timeoutcopy,tvend);\r
+ timeout.tv_sec := timeoutcopy.tv_sec;\r
+ timeout.tv_usec := timeoutcopy.tv_usec;\r
+ if (timeout.tv_sec < 0) then begin\r
+ timeout.tv_sec := 0;\r
+ timeout.tv_usec := 0;\r
+ end;\r
+ {$endif} //select_no_autotv\r
end;\r
+\r
{$ifndef nosignal}\r
sigprocmask(SIG_BLOCK,@blockset,nil);\r
{$endif}\r