(************************************************************************) (* v * The Coq Proof Assistant / The Coq Development Team *) (* prerr_endline (Printf.sprintf "Handshake with %d OK" pid); output_value cout (Hello (proto_version,Unix.getpid ())); flush cout | _ -> raise (Failure "handshake protocol") with | Failure s | Invalid_argument s | Sys_error s -> pr_err ("Handshake failed: " ^ s); raise (Failure "handshake") | End_of_file -> pr_err "Handshake failed: End_of_file"; raise (Failure "handshake") let open_bin_connection h pr pw = let open Unix in let _, cout = open_connection (ADDR_INET (inet_addr_of_string h,pr)) in let cin, _ = open_connection (ADDR_INET (inet_addr_of_string h,pw)) in set_binary_mode_in cin true; set_binary_mode_out cout true; let cin = CThread.prepare_in_channel_for_thread_friendly_io cin in cin, cout let controller h pr pw = prerr_endline "starting controller thread"; let main () = let ic, oc = open_bin_connection h pr pw in let rec loop () = try match CThread.thread_friendly_input_value ic with | Hello _ -> prerr_endline "internal protocol error"; exit 1 | ReqDie -> prerr_endline "death sentence received"; exit 0 | ReqStats -> output_value oc (RespStats (Gc.quick_stat ())); flush oc; loop () with | e -> prerr_endline ("control channel broken: " ^ Printexc.to_string e); exit 1 in loop () in ignore(Thread.create main ()) let main_channel = ref None let control_channel = ref None let channels = ref None let init_channels () = if !channels <> None then Errors.anomaly(Pp.str "init_channels called twice"); let () = match !main_channel with | None -> () | Some (Socket(mh,mpr,mpw)) -> channels := Some (open_bin_connection mh mpr mpw); | Some AnonPipe -> let stdin = Unix.in_channel_of_descr (Unix.dup Unix.stdin) in let stdout = Unix.out_channel_of_descr (Unix.dup Unix.stdout) in Unix.dup2 Unix.stderr Unix.stdout; set_binary_mode_in stdin true; set_binary_mode_out stdout true; let stdin = CThread.prepare_in_channel_for_thread_friendly_io stdin in channels := Some (stdin, stdout); in match !control_channel with | None -> () | Some (Socket (ch, cpr, cpw)) -> controller ch cpr cpw | Some AnonPipe -> Errors.anomaly (Pp.str "control channel cannot be a pipe") let get_channels () = match !channels with | None -> Printf.eprintf "Fatal error: ideslave communication channels not set.\n"; exit 1 | Some(ic, oc) -> ic, oc