diff --git a/dispatch.ml b/dispatch.ml index c1fa9d5..24c38f2 100644 --- a/dispatch.ml +++ b/dispatch.ml @@ -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 - - diff --git a/tests.ml b/tests.ml index 81bafbd..3ac0bad 100644 --- a/tests.ml +++ b/tests.ml @@ -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];