Summary: This will be needed higher up in the stack because the new `ProcessPool` module will need to call into `Logging` to refresh the logging formatters to get the right PID when writing to the log file. +remove dead code `iter_parallel` Reviewed By: jberdine Differential Revision: D5165130 fbshipit-source-id: 95c949bmaster
parent
f4b9bb3e3b
commit
0404641ab3
@ -0,0 +1,34 @@
|
|||||||
|
(*
|
||||||
|
* Copyright (c) 2017 - present Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*)
|
||||||
|
open! IStd
|
||||||
|
|
||||||
|
module F = Format
|
||||||
|
|
||||||
|
(* Run the epilogues when we get SIGINT (Control-C). We do not want to mask SIGINT unless at least
|
||||||
|
one epilogue has been registered, so make this value lazy. *)
|
||||||
|
let activate_run_epilogues_on_signal = lazy (
|
||||||
|
let run_epilogues_on_signal s =
|
||||||
|
F.eprintf "*** %s: Caught %s, time to die@." (Filename.basename Sys.executable_name)
|
||||||
|
(Signal.to_string s);
|
||||||
|
(* Epilogues are registered with [at_exit] so exiting will make them run. *)
|
||||||
|
exit 0 in
|
||||||
|
Signal.Expert.handle Signal.int run_epilogues_on_signal
|
||||||
|
)
|
||||||
|
|
||||||
|
let register ~f desc =
|
||||||
|
let f_no_exn () =
|
||||||
|
if not !ProcessPool.in_child then
|
||||||
|
try
|
||||||
|
f ()
|
||||||
|
with exn ->
|
||||||
|
F.eprintf "Error while running epilogue %s:@ %a.@ Powering through...@." desc Exn.pp exn in
|
||||||
|
(* We call `exit` in a bunch of places, so register the epilogues with [at_exit]. *)
|
||||||
|
Pervasives.at_exit f_no_exn;
|
||||||
|
(* Register signal masking. *)
|
||||||
|
Lazy.force activate_run_epilogues_on_signal
|
@ -0,0 +1,13 @@
|
|||||||
|
(*
|
||||||
|
* Copyright (c) 2017 - present Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*)
|
||||||
|
open! IStd
|
||||||
|
|
||||||
|
(** Register a function to run when the program exits or is interrupted. Registered functions are
|
||||||
|
run in the reverse order in which they were registered. *)
|
||||||
|
val register : f:(unit -> unit) -> string -> unit
|
@ -0,0 +1,52 @@
|
|||||||
|
(*
|
||||||
|
* Copyright (c) 2017 - present Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*)
|
||||||
|
open! IStd
|
||||||
|
|
||||||
|
(* Keep track of whether the current execution is in a child process *)
|
||||||
|
let in_child = ref false
|
||||||
|
|
||||||
|
type t =
|
||||||
|
{
|
||||||
|
mutable num_processes : int;
|
||||||
|
jobs : int;
|
||||||
|
}
|
||||||
|
let create ~jobs =
|
||||||
|
{
|
||||||
|
num_processes = 0;
|
||||||
|
jobs;
|
||||||
|
}
|
||||||
|
|
||||||
|
let incr counter =
|
||||||
|
counter.num_processes <- counter.num_processes + 1
|
||||||
|
|
||||||
|
let decr counter =
|
||||||
|
counter.num_processes <- counter.num_processes - 1
|
||||||
|
|
||||||
|
let wait counter =
|
||||||
|
let _ = Unix.wait `Any in
|
||||||
|
decr counter
|
||||||
|
|
||||||
|
let wait_all counter =
|
||||||
|
for _ = 1 to counter.num_processes do
|
||||||
|
wait counter
|
||||||
|
done
|
||||||
|
|
||||||
|
let should_wait counter =
|
||||||
|
counter.num_processes >= counter.jobs
|
||||||
|
|
||||||
|
let start_child ~f ~pool x =
|
||||||
|
match Unix.fork () with
|
||||||
|
| `In_the_child ->
|
||||||
|
in_child := true;
|
||||||
|
f x;
|
||||||
|
exit 0
|
||||||
|
| `In_the_parent _pid ->
|
||||||
|
incr pool;
|
||||||
|
if should_wait pool
|
||||||
|
then wait pool
|
@ -0,0 +1,24 @@
|
|||||||
|
(*
|
||||||
|
* Copyright (c) 2017 - present Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*)
|
||||||
|
open! IStd
|
||||||
|
|
||||||
|
(** Pool of processes to execute in parallel up to a number of jobs. *)
|
||||||
|
type t
|
||||||
|
|
||||||
|
(** Create a new pool of processes *)
|
||||||
|
val create : jobs:int -> t
|
||||||
|
|
||||||
|
(** Start a new child process in the pool.
|
||||||
|
If all the jobs are taken, wait until one is free. *)
|
||||||
|
val start_child : f:('a -> unit) -> pool:t -> 'a -> unit
|
||||||
|
|
||||||
|
(** Wait until all the currently executing processes terminate *)
|
||||||
|
val wait_all : t -> unit
|
||||||
|
|
||||||
|
val in_child : bool ref
|
Loading…
Reference in new issue