aboutsummaryrefslogtreecommitdiff
path: root/lib/cThread.ml
diff options
context:
space:
mode:
authorEnrico Tassi2014-01-29 23:08:45 +0100
committerEnrico Tassi2014-01-30 17:29:33 +0100
commit8c4b6ebb338c8a61c607782908254aadead0c3cd (patch)
tree2cf4c79b5911c1853bcdd16cbe6d9ca3bab686f3 /lib/cThread.ml
parent0a61e18a60fe05b989c24f28c769c3b0cd296cf1 (diff)
Work around for bug in threads + blocking io streamlined
Diffstat (limited to 'lib/cThread.ml')
-rw-r--r--lib/cThread.ml48
1 files changed, 48 insertions, 0 deletions
diff --git a/lib/cThread.ml b/lib/cThread.ml
new file mode 100644
index 0000000000..a38c88d802
--- /dev/null
+++ b/lib/cThread.ml
@@ -0,0 +1,48 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2012 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+let prepare_in_channel_for_thread_friendly_io ic =
+ Unix.set_nonblock (Unix.descr_of_in_channel ic)
+
+let thread_friendly_read_fd fd s ~off ~len =
+ let rec loop () =
+ try Unix.read fd s off len
+ with Unix.Unix_error((Unix.EWOULDBLOCK|Unix.EAGAIN),_,_) ->
+ while not (Thread.wait_timed_read fd 1.0) do Thread.yield () done;
+ loop ()
+ in
+ loop ()
+
+let thread_friendly_read ic s ~off ~len =
+ try
+ let fd = Unix.descr_of_in_channel ic in
+ thread_friendly_read_fd fd s ~off ~len
+ with Unix.Unix_error _ -> 0
+
+let really_read_fd fd s off len =
+ let i = ref 0 in
+ while !i < len do
+ let off = off + !i in
+ let len = len - !i in
+ let r = thread_friendly_read_fd fd s ~off ~len in
+ if r = 0 then raise End_of_file;
+ i := !i + r
+ done
+
+let thread_friendly_input_value ic =
+ try
+ let fd = Unix.descr_of_in_channel ic in
+ let header = String.create Marshal.header_size in
+ really_read_fd fd header 0 Marshal.header_size;
+ let body_size = Marshal.data_size header 0 in
+ let msg = String.create (body_size + Marshal.header_size) in
+ String.blit header 0 msg 0 Marshal.header_size;
+ really_read_fd fd msg Marshal.header_size body_size;
+ Marshal.from_string msg 0
+ with Unix.Unix_error _ -> raise End_of_file
+