File: libextunix.ml

package info (click to toggle)
cothreads 0.10-7
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 500 kB
  • sloc: ml: 1,963; makefile: 216
file content (41 lines) | stat: -rw-r--r-- 1,584 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
open Unix

(* Atomically write OCaml value to file_descr for both block/nonblock mode *) 
let marshal_write =
  let rec write_rec fd s ofs len =
    let len' = 
      try write fd s ofs len 
      with Unix_error ((EAGAIN|EWOULDBLOCK),_,_) when ofs > 0 -> 0 in
    match len' with
    | 0 -> ignore (select [] [fd] [] (-1.)); write_rec fd s ofs len
    | _ when len' < len -> write_rec fd s (ofs   len') (len - len')
    | _ -> () in
  fun v fd ->
    let str = Marshal.to_string v [Marshal.Closures] in
    write_rec fd (Bytes.of_string str) 0 (String.length str)

(* Atomically read OCaml value from file_descr for both block/nonblock mode *) 
let marshal_read fd =
  let bsize = Marshal.header_size   128 in
  let buf = Bytes.create bsize in
  let rec read_rec fd buf ofs len =
    let len' =
      try Some (read fd buf ofs len) with 
      | Unix_error (EAGAIN,_,_) 
      | Unix_error (EWOULDBLOCK,_,_) when ofs > 0 -> None
      | e -> raise e in
    match len' with
    | Some 0 -> raise End_of_file
    | Some l when l = len -> ()
    | Some l -> read_rec fd buf (ofs   l) (len -l)
    | None -> ignore (select [fd] [] [] (-1.)); read_rec fd buf ofs len in
  read_rec fd buf 0 Marshal.header_size;
  let data_size = Marshal.data_size buf 0 in
  let total_size = Marshal.header_size   data_size in
  let buf = 
    if total_size <= Bytes.length buf then buf else
      let ext_buf = Bytes.create total_size in
      Bytes.blit buf 0 ext_buf 0 Marshal.header_size;
      ext_buf in
  read_rec fd buf Marshal.header_size data_size;
  Marshal.from_string (Bytes.to_string buf) 0