(* This file is free software, part of containers. See file "license" for more details. *) (** {1 Thread Pool, and Futures} Renamed and heavily updated from [CCFuture] @since NEXT_RELEASE *) type +'a state = | Done of 'a | Waiting | Failed of exn module type PARAM = sig val min_size : int (** Minimum number of threads in the pool *) val max_size : int (** Maximum number of threads in the pool *) end exception Stopped (** {2 Create a new Pool} *) module Make(P : PARAM) : sig val run : (unit -> _) -> unit (** [run f] schedules [f] for being executed in the thread pool *) val run1 : ('a -> _) -> 'a -> unit (** [run1 f x] is similar to [run (fun () -> f x)] *) val run2 : ('a -> 'b -> _) -> 'a -> 'b -> unit val run3 : ('a -> 'b -> 'c -> _) -> 'a -> 'b -> 'c -> unit val set_exn_handler : (exn -> unit) -> unit val active : unit -> bool (** [active ()] is true as long as [stop()] has not been called yet *) val stop : unit -> unit (** After calling [stop ()], Most functions will raise Stopped. This has the effect of preventing new tasks from being executed. *) (** {6 Futures} The futures are registration points for callbacks, storing a {!state}, that are executed in the pool using {!run}. *) module Fut : sig type 'a t (** A future value of type 'a *) type 'a future = 'a t (** {2 Constructors} *) val return : 'a -> 'a t (** Future that is already computed *) val fail : exn -> 'a t (** Future that fails immediately *) val make : (unit -> 'a) -> 'a t (** Create a future, representing a value that will be computed by the function. If the function raises, the future will fail. *) val make1 : ('a -> 'b) -> 'a -> 'b t val make2 : ('a -> 'b -> 'c) -> 'a -> 'b -> 'c t (** {2 Basics} *) val get : 'a t -> 'a (** Blocking get: wait for the future to be evaluated, and get the value, or the exception that failed the future is returned. raise e if the future failed with e *) val state : 'a t -> 'a state (** State of the future *) val is_done : 'a t -> bool (** Is the future evaluated (success/failure)? *) (** {2 Combinators} *) val on_success : 'a t -> ('a -> unit) -> unit (** Attach a handler to be called upon success. The handler should not call functions on the future. Might be evaluated now if the future is already done. *) val on_failure : _ t -> (exn -> unit) -> unit (** Attach a handler to be called upon failure. The handler should not call any function on the future. Might be evaluated now if the future is already done. *) val on_finish : 'a t -> ('a state -> unit) -> unit (** Attach a handler to be called when the future is evaluated. The handler should not call functions on the future. Might be evaluated now if the future is already done. *) val flat_map : ('a -> 'b t) -> 'a t -> 'b t (** Monadic combination of futures *) val and_then : 'a t -> (unit -> 'b t) -> 'b t (** Wait for the first future to succeed, then launch the second *) val sequence_a : 'a t array -> 'a array t (** Future that waits for all previous futures to terminate. If any future in the array fails, [sequence_a l] fails too. *) val map_a : ('a -> 'b t) -> 'a array -> 'b array t (** [map_l f a] maps [f] on every element of [a], and will return the array of every result if all calls succeed, or an error otherwise. *) val sequence_l : 'a t list -> 'a list t (** Future that waits for all previous futures to terminate. If any future in the list fails, [sequence_l l] fails too. *) val map_l : ('a -> 'b t) -> 'a list -> 'b list t (** [map_l f l] maps [f] on every element of [l], and will return the list of every result if all calls succeed, or an error otherwise. *) val choose_a : 'a t array -> 'a t (** Choose among those futures (the first to terminate). Behaves like the first future that terminates, by failing if the future fails *) val choose_l : 'a t list -> 'a t (** Choose among those futures (the first to terminate). Behaves like the first future that terminates, by failing if the future fails *) val map : ('a -> 'b) -> 'a t -> 'b t (** Maps the value inside the future. The function doesn't run in its own task; if it can take time, use {!flat_map} or {!map_async} *) val map_async : ('a -> 'b) -> 'a t -> 'b t (** Maps the value inside the future, to be computed in a separated job. *) val app : ('a -> 'b) t -> 'a t -> 'b t (** [app f x] applies the result of [f] to the result of [x] *) val app_async : ('a -> 'b) t -> 'a t -> 'b t (** [app f x] applies the result of [f] to the result of [x], in a separated job scheduled in the pool *) val sleep : float -> unit t (** Future that returns with success in the given amount of seconds. Blocks the thread! If you need to wait on many events, consider using {!CCTimer}. *) module Infix : sig val (>>=) : 'a t -> ('a -> 'b t) -> 'b t val (>>) : 'a t -> (unit -> 'b t) -> 'b t val (>|=) : 'a t -> ('a -> 'b) -> 'b t val (<*>) : ('a -> 'b) t -> 'a t -> 'b t end val (>>=) : 'a t -> ('a -> 'b t) -> 'b t val (>>) : 'a t -> (unit -> 'b t) -> 'b t val (>|=) : 'a t -> ('a -> 'b) -> 'b t (** Alias to {!map} *) val (<*>): ('a -> 'b) t -> 'a t -> 'b t (** Alias to {!app} *) end end