X-Git-Url: http://www.lcore.org/git/lcore.git/blobdiff_plain/9763940f8849e5c807566157829a1e6d2c9172ee..2e969e5e75fb8f544ff468584fb4e33d891e2954:/lcoreselect.pas diff --git a/lcoreselect.pas b/lcoreselect.pas index f613f67..d3685ae 100644 --- a/lcoreselect.pas +++ b/lcoreselect.pas @@ -69,7 +69,7 @@ var temptimer : tltimer ; begin - gettimeofday(tvnow); + gettimemonotonic(tvnow); currenttimer := firsttimer; while assigned(currenttimer) do begin //writeln(currenttimer.enabled); @@ -190,7 +190,7 @@ begin prepsigpipe; {$endif} selectresult := select(maxs+1,@fdsr,@fdsw,nil,0); - while (selectresult>0) or assigned(firsttask) or assigned(currenttask) do begin; + while (selectresult>0) or assigned(firsttask) do begin; processtasks; processtimers; @@ -220,10 +220,22 @@ begin end; +{ +select in linux/sysV subtracts from timeout for time spent in it, but in BSD it doesn't +enabling select_no_autotv here makes doSelect mimic the decrement behavior, in case the caller needs it +the caller here in lcoreselect does not need it, and enabling it would have a slight perf hit. +it is safe for this to be enabled even if the OS does it too (it will not subtract twice) +it is currently disabled but can be enabled if needed +} +{$ifndef linux}{-$define select_no_autotv}{$endif} + Function doSelect(timeOut:PTimeVal):longint;//inline; var localtimeval : ttimeval; maxslocal : integer; + {$ifdef select_no_autotv} + timeoutcopy,tvstart,tvend : ttimeval; + {$endif} begin //unblock signals //zeromemory(@sset,sizeof(sset)); @@ -243,18 +255,46 @@ begin {$ifndef nosignal} sigprocmask(SIG_UNBLOCK,@blockset,nil); {$endif} + + {$ifdef select_no_autotv} + if assigned(timeout) then begin + timeoutcopy.tv_sec := timeOut.tv_sec; + timeoutcopy.tv_usec := timeOut.tv_usec; + gettimemonotonic(tvstart); + end; + {$endif} + result := select(maxslocal+1,@FDSR,@FDSW,nil,timeout); if result <= 0 then begin fd_zero(FDSR); fd_zero(FDSW); if result=-1 then begin if linuxerror = SYS_EINTR then begin - // we received a signal it's not a problem + // we received a signal it is not a problem end else begin raise esocketexception.create('select returned error '+inttostr(linuxerror)); end; + end + {$ifdef select_no_autotv} + else if (result = 0) and assigned(timeout) then begin + //timeout reached: zero the timeval + timeout.tv_sec := 0; + timeout.tv_usec := 0; end; + end else if assigned(timeout) then begin + //successful result: subtract elapsed time + gettimemonotonic(tvend); + tv_subtract(tvend,tvstart); + tv_subtract(timeoutcopy,tvend); + timeout.tv_sec := timeoutcopy.tv_sec; + timeout.tv_usec := timeoutcopy.tv_usec; + if (timeout.tv_sec < 0) then begin + timeout.tv_sec := 0; + timeout.tv_usec := 0; + end; + {$endif} //select_no_autotv end; + {$ifndef nosignal} sigprocmask(SIG_BLOCK,@blockset,nil); {$endif} @@ -309,7 +349,7 @@ begin selectresult := doselect(nil); end else begin - gettimeofday(tvnow); + gettimemonotonic(tvnow); tv_subtract(tv,tvnow); //writeln('timers active');