package async_kernel
Monadic concurrency library
Install
Dune Dependency
Authors
Maintainers
Sources
v0.17.0.tar.gz
sha256=01ced973dbc70535f692f38bed524ae82dba17e26e58791b2fbf0d647b160d2e
doc/src/async_kernel/deferred0.ml.html
Source file deferred0.ml
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 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
open! Core open! Import module Ivar = Ivar0 module Handler = Ivar.Handler (* Deferreds present a covariant view of ivars. We could actually implement deferreds using a record of closures, as in the [essence_of_deferred] record below, for which the OCaml type checker can infer covariance. However, doing so would make [Ivar.read] very costly, because it would have to allocate lots of closures and a record. Instead of doing this, we make deferreds an abstract covariant type, which concretely is just the ivar, and use [Obj.magic] to convert back and forth between a deferred and its concrete representation as an ivar. This [Obj.magic] is safe because the representation is always just an ivar, and the covariance follows from the fact that all the deferred operations are equivalent to those implemented directly on top of the [essence_of_deferred]. {[ type (+'a, 'execution_context) essence_of_deferred = { peek : unit -> 'a option ; is_determined : unit -> bool ; upon : ('a -> unit) -> unit ; upon' : ('a -> unit) -> Unregister.t ; install_removable_handler : ('a, 'execution_context) Raw_handler.t -> Unregister.t; } ]} *) type +'a t = 'a Types.Deferred.t (* the abstract covariant type, equivalent to ivar *) let of_ivar (type a) (ivar : a Ivar.t) : a t = Obj.magic ivar let to_ivar (type a) t : a Ivar.t = Obj.magic (t : a t) let invariant invariant_a t = Ivar.invariant invariant_a (to_ivar t) let sexp_of_t sexp_of_a t = Ivar.sexp_of_t sexp_of_a (to_ivar t) let peek t = Ivar.peek (to_ivar t) let return a = of_ivar (Ivar.create_full a) let is_determined t = Ivar.is_full (to_ivar t) let value_exn t = Ivar.value (to_ivar t) ~if_empty_then_failwith:"Deferred.value_exn called on undetermined deferred" ;; let upon t f = Ivar.upon (to_ivar t) f let create f = let result = Ivar.create () in f result; of_ivar result ;; (* don't use [create] here as it would allocate one more closure *) let bind t ~f = let bind_result = Ivar.create () in upon t (fun a -> Ivar.connect ~bind_result ~bind_rhs:(to_ivar (f a))); of_ivar bind_result ;; let add_handler t f execution_context = Ivar.add_handler (to_ivar t) f execution_context let remove_handler t h = Ivar.remove_handler (to_ivar t) h
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>