|
20 | 20 |
|
21 | 21 | (** OCaml low level implementation of the shout source protocol. *)
|
22 | 22 |
|
23 |
| -external poll : |
24 |
| - Unix.file_descr array -> |
25 |
| - Unix.file_descr array -> |
26 |
| - Unix.file_descr array -> |
27 |
| - float -> |
28 |
| - Unix.file_descr array * Unix.file_descr array * Unix.file_descr array |
29 |
| - = "caml_cry_poll" |
30 |
| - |
31 |
| -let poll r w e timeout = |
32 |
| - let r = Array.of_list r in |
33 |
| - let w = Array.of_list w in |
34 |
| - let e = Array.of_list e in |
35 |
| - let r, w, e = poll r w e timeout in |
36 |
| - (Array.to_list r, Array.to_list w, Array.to_list e) |
37 |
| - |
38 |
| -let select = match Sys.os_type with "Unix" -> poll | _ -> Unix.select |
| 23 | +let poll r w timeout = |
| 24 | + let timeout = |
| 25 | + match timeout with |
| 26 | + | x when x < 0. -> Poll.Timeout.never |
| 27 | + | 0. -> Poll.Timeout.immediate |
| 28 | + | x -> |
| 29 | + let frac, int = modf x in |
| 30 | + let int = Int64.mul (Int64.of_float int) 1_000_000_000L in |
| 31 | + let frac = Int64.of_float (frac *. 1_000_000_000.) in |
| 32 | + let timeout = Int64.add int frac in |
| 33 | + Poll.Timeout.after timeout |
| 34 | + in |
| 35 | + let poll = Poll.create () in |
| 36 | + List.iter (fun fd -> Poll.set poll fd Poll.Event.read) r; |
| 37 | + List.iter (fun fd -> Poll.set poll fd Poll.Event.write) w; |
| 38 | + ignore (Poll.wait poll timeout); |
| 39 | + let r = ref [] in |
| 40 | + let w = ref [] in |
| 41 | + Poll.iter_ready poll ~f:(fun fd event -> |
| 42 | + if event.Poll.Event.readable then r := fd :: !r; |
| 43 | + if event.Poll.Event.writable then w := fd :: !w); |
| 44 | + (!r, !w) |
39 | 45 |
|
40 | 46 | type error =
|
41 | 47 | | Create of exn
|
@@ -90,9 +96,8 @@ let wait_for ?(log = fun _ -> ()) event timeout =
|
90 | 96 | | `Both socket -> ([socket], [socket])
|
91 | 97 | in
|
92 | 98 | let rec wait t =
|
93 |
| - let r, w, _ = |
94 |
| - try select r w [] t |
95 |
| - with Unix.Unix_error (Unix.EINTR, _, _) -> ([], [], []) |
| 99 | + let r, w = |
| 100 | + try poll r w t with Unix.Unix_error (Unix.EINTR, _, _) -> ([], []) |
96 | 101 | in
|
97 | 102 | if r = [] && w = [] then (
|
98 | 103 | let current_time = Unix.gettimeofday () in
|
@@ -164,8 +169,8 @@ let connect_sockaddr ?bind_address ?timeout sockaddr =
|
164 | 169 | let do_timeout = timeout <> None in
|
165 | 170 | let check_timeout () =
|
166 | 171 | let timeout = Option.get timeout in
|
167 |
| - (* Block in a select call for [timeout] seconds. *) |
168 |
| - let _, w, _ = select [] [socket] [] timeout in |
| 172 | + (* Block in a poll call for [timeout] seconds. *) |
| 173 | + let _, w = poll [] [socket] timeout in |
169 | 174 | if w = [] then raise Timeout;
|
170 | 175 | match Unix.getsockopt_error socket with
|
171 | 176 | | Some err -> raise (Unix.Unix_error (err, "connect", ""))
|
|
0 commit comments