diff options
-rw-r--r-- | ide/coq.ml | 1 | ||||
-rw-r--r-- | ide/ideutils.ml | 23 | ||||
-rw-r--r-- | ide/ideutils.mli | 3 |
3 files changed, 17 insertions, 10 deletions
diff --git a/ide/coq.ml b/ide/coq.ml index 78e917bdb..f165d2013 100644 --- a/ide/coq.ml +++ b/ide/coq.ml @@ -321,6 +321,7 @@ let open_process_pid prog args = assert (pid <> 0); Unix.close ide2top_r; Unix.close top2ide_w; + Unix.set_nonblock top2ide_r; (pid,top2ide_r,Unix.out_channel_of_descr ide2top_w) exception TubeError diff --git a/ide/ideutils.ml b/ide/ideutils.ml index e1c57074b..8f5417551 100644 --- a/ide/ideutils.ml +++ b/ide/ideutils.ml @@ -287,7 +287,7 @@ let stat f = Note: In a mono-thread coqide, we use the same buffer for different read operations *) -let maxread = 1024 +let maxread = 8192 let read_string = String.create maxread let read_buffer = Buffer.create maxread @@ -305,22 +305,27 @@ let read_file name buf = close_in ic with e -> close_in ic; raise e -(** Read a gtk asynchronous channel *) +(** Read what is available on a gtk channel. This channel should have been + set as non-blocking. When there's nothing more to read, the inner loop + will be exited via a GError exception concerning a EAGAIN unix error. + Anyway, any other exception also stops the read. *) let io_read_all chan = Buffer.clear read_buffer; - let rec loop () = - let len = Glib.Io.read ~buf:read_string ~pos:0 ~len:maxread chan in - Buffer.add_substring read_buffer read_string 0 len; - if len < maxread then Buffer.contents read_buffer - else loop () - in loop () + let read_once () = + let len = Glib.Io.read_chars ~buf:read_string ~pos:0 ~len:maxread chan in + Buffer.add_substring read_buffer read_string 0 len + in + begin try while true do read_once () done with _ -> () end; + Buffer.contents read_buffer (** Run an external command asynchronously *) let run_command display finally cmd = let cin = Unix.open_process_in cmd in - let io_chan = Glib.Io.channel_of_descr (Unix.descr_of_in_channel cin) in + let fd = Unix.descr_of_in_channel cin in + let () = Unix.set_nonblock fd in + let io_chan = Glib.Io.channel_of_descr fd in let all_conds = [`ERR; `HUP; `IN; `NVAL; `PRI] in (* all except `OUT *) let rec has_errors = function | [] -> false diff --git a/ide/ideutils.mli b/ide/ideutils.mli index 87ddb2a95..cc34a355a 100644 --- a/ide/ideutils.mli +++ b/ide/ideutils.mli @@ -80,7 +80,8 @@ val stat : string -> stats val read_file : string -> Buffer.t -> unit -(** Read the available content on some gtk asynchronous input channel *) +(** Read what is available on a gtk input channel. + This channel should have been set as non-blocking. *) val io_read_all : Glib.Io.channel -> string |