package picos
Pico scheduler framework
Install
Dune Dependency
Authors
Maintainers
Sources
picos-0.3.0.tbz
sha256=544804c0bde4b29764f82f04e7defed7c06bc43e5a6ce3f7fdc326cb54a7f066
sha512=4c93427e477fb52374a554a8b9c4c92836a9b5899161275d1473269ab526a1f59177209140631ed763a55be375855dea12f076e18bf4124522414986c0e257be
doc/src/picos.structured/finally.ml.html
Source file finally.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 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
open Picos type 'a finally = ('a -> unit) * (unit -> 'a) let[@inline] finally release acquire = (release, acquire) (** This function is marked [@inline never] to ensure that there are no allocations between the [acquire ()] and the [match ... with] nor before [release]. Allocations here would mean that e.g. pressing Ctrl-C, i.e. [SIGINT], at the right moment could mean that [release] would not be called after [acquire]. *) let[@inline never] ( let@ ) (release, acquire) body = let x = acquire () in match body x with | y -> release x; y | exception exn -> release x; raise exn type ('a, _) tdt = | Nothing : ('a, [> `Nothing ]) tdt | Resource : { mutable resource : 'a; release : 'a -> unit; moved : Trigger.t; } -> ('a, [> `Resource ]) tdt type 'a moveable = ('a, [ `Nothing | `Resource ]) tdt Atomic.t let ( let^ ) (release, acquire) body = let moveable = Atomic.make Nothing in let acquire () = let (Resource r as state : (_, [ `Resource ]) tdt) = Resource { resource = Obj.magic (); release; moved = Trigger.create () } in r.resource <- acquire (); Atomic.set moveable state; moveable in let release moveable = match Atomic.get moveable with | Nothing -> () | Resource r -> begin match Trigger.await r.moved with | None -> () | Some exn_bt -> begin match Atomic.exchange moveable Nothing with | Nothing -> () | Resource r -> r.release r.resource; Exn_bt.raise exn_bt end end in ( let@ ) (release, acquire) body let[@inline never] check_no_resource () = (* In case of cancelation this is not considered an error as the resource was (likely) released by the parent. *) Fiber.check (Fiber.current ()); invalid_arg "no resource to move" let move moveable = match Atomic.get moveable with | Nothing -> check_no_resource () | Resource r -> let acquire () = match Atomic.exchange moveable Nothing with | Nothing -> check_no_resource () | Resource r -> Trigger.signal r.moved; r.resource in (r.release, acquire)
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>