64 lines
2.0 KiB
OCaml
64 lines
2.0 KiB
OCaml
(***********************************************************************)
|
|
(* *)
|
|
(* OCaml *)
|
|
(* *)
|
|
(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)
|
|
(* *)
|
|
(* Copyright 1996 Institut National de Recherche en Informatique et *)
|
|
(* en Automatique. All rights reserved. This file is distributed *)
|
|
(* under the terms of the Q Public License version 1.0. *)
|
|
(* *)
|
|
(***********************************************************************)
|
|
|
|
open Event
|
|
|
|
type 'a buffer_channel = {
|
|
input: 'a channel;
|
|
output: 'a channel;
|
|
thread: Thread.t;
|
|
}
|
|
|
|
let new_buffer_channel() =
|
|
let ic = new_channel() in
|
|
let oc = new_channel() in
|
|
let rec buffer_process front rear =
|
|
match (front, rear) with
|
|
| (["EOF"], []) -> Thread.exit ()
|
|
| ([], []) -> buffer_process [sync(receive ic)] []
|
|
| (hd::tl, _) ->
|
|
select [
|
|
wrap (receive ic) (fun x -> buffer_process front (x::rear));
|
|
wrap (send oc hd) (fun () -> buffer_process tl rear)
|
|
]
|
|
| ([], _) -> buffer_process (List.rev rear) [] in
|
|
let t = Thread.create (buffer_process []) [] in
|
|
{ input = ic; output = oc; thread = t }
|
|
|
|
let buffer_send bc data =
|
|
sync(send bc.input data)
|
|
|
|
let buffer_receive bc =
|
|
receive bc.output
|
|
|
|
(* Test *)
|
|
|
|
let box = new_buffer_channel()
|
|
let ch = new_channel()
|
|
|
|
let f () =
|
|
buffer_send box "un";
|
|
buffer_send box "deux";
|
|
sync (send ch 3)
|
|
|
|
let g () =
|
|
print_int (sync(receive ch)); print_newline();
|
|
print_string (sync(buffer_receive box)); print_newline();
|
|
print_string (sync(buffer_receive box)); print_newline()
|
|
|
|
let _ =
|
|
let t = Thread.create f () in
|
|
g();
|
|
buffer_send box "EOF";
|
|
Thread.join box.thread;
|
|
Thread.join t
|