Tweak for timers with no fd activity

Turns out the timeout value for select() and friends is an upper boundary.
once was being run as many as 12 times in a tight loop before a timer
expired.  I added a fudge factor of 0.001 seconds, and that seems to have
fixed it for most cases.
This commit is contained in:
Neale Pickett 2008-03-18 10:55:31 -06:00
parent eeab6fc319
commit 9f058248ba
2 changed files with 13 additions and 6 deletions

View File

@ -21,6 +21,14 @@ type t = {
timers : Timer.t ref;
}
(* select(), poll(), and epoll() treat timeout as an upper bound of time
to wait. This fudge factor helps ensure that given no FD activity,
this isn't run in a tight loop as a timer approaches. This value was
determined experimentally on a 1.25GHz G4 PPC to work most of the
time. Your mileage may vary. *)
let timeout_fudge = 0.001
let to_epoll = function
| Input -> Epoll.In
| Priority -> Epoll.Priority
@ -105,7 +113,7 @@ let once d =
let timeout =
try
let (time, _) = Timer.min_elt !(d.timers) in
let delta = (time -. now) in
let delta = (time -. now +. timeout_fudge) in
max delta 0.0
with Not_found ->
(-1.0)
@ -129,5 +137,3 @@ let rec run d =
once d;
run d
end

View File

@ -276,9 +276,10 @@ let unit_tests =
assert_equal ~printer:string_of_float 0.0 !last_timer;
Dispatch.modify d b [Dispatch.Input];
while !last_timer = 0.0 do
Dispatch.once d
done;
Dispatch.once d;
if (!last_timer = 0.0) then
(* Give it one chance *)
Dispatch.once d;
assert_equal ~printer:string_of_float time !last_timer;
Dispatch.modify d b [Dispatch.Input; Dispatch.Output];