package picos_std
Sample libraries for Picos
Install
Dune Dependency
Authors
Maintainers
Sources
picos-0.5.0.tbz
sha256=862d61383e2df93a876bedcffb1fd1ddc0f96c50b0e9c07943a2aee1f0e182be
sha512=87805379017ef4a7f2c11b954625a3757a0f1431bb9ba59132202de278b3e41adbe0cdc20e3ab23b7c9a8c5a15faeb7ec79348e7d80f2b14274b00df0893b8c0
doc/src/picos_std.finally/picos_std_finally.ml.html
Source file picos_std_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 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
open Picos type ('a, _) tdt = | Transferred : ('a, [> `Transferred ]) tdt | Borrowed : ('a, [> `Borrowed ]) tdt | Dropped : ('a, [> `Dropped ]) tdt | Resource : { mutable resource : 'a; release : 'a -> unit; transferred_or_dropped : Trigger.t; } -> ('a, [> `Resource ]) tdt type 'a instance = ('a, [ `Transferred | `Borrowed | `Dropped | `Resource ]) tdt Atomic.t (* *) let[@inline never] error (case : (_, [< `Transferred | `Borrowed | `Dropped ]) tdt) = invalid_arg (match case with | Transferred -> "transferred" | Dropped -> "dropped" | Borrowed -> "borrowed") let[@inline never] check_released () = (* In case of cancelation we do not consider being released an error as the resource was released by (the |an)other party involved in the [move]. *) Fiber.check (Fiber.current ()); error Dropped (* *) let rec drop instance = match Atomic.get instance with | Transferred | Dropped -> () | Borrowed as case -> error case | Resource r as before -> if Atomic.compare_and_set instance before Dropped then begin r.release r.resource; Trigger.signal r.transferred_or_dropped end else drop instance (* *) let await_transferred_or_dropped instance = match Atomic.get instance with | Transferred | Dropped -> () | Borrowed as case -> (* This should be impossible as [let@ _ = borrow _ in _] should have restored the state. *) error case | Resource r -> begin match Trigger.await r.transferred_or_dropped with | None -> (* We release in case we could not wait. *) drop instance | Some (exn, bt) -> (* We have been canceled, so we release. *) drop instance; Printexc.raise_with_backtrace exn bt end let[@inline never] instantiate release acquire scope = let instance = Sys.opaque_identity begin let transferred_or_dropped = Trigger.create () in let state = Resource { resource = Obj.magic (); release; transferred_or_dropped } in Atomic.make state end in (* After this point there must be no allocations before [acquire ()]. *) let (Resource r : (_, [ `Resource ]) tdt) = Obj.magic (Atomic.get instance) in r.resource <- acquire (); match scope instance with | result -> await_transferred_or_dropped instance; result | exception exn -> let bt = Printexc.get_raw_backtrace () in drop instance; Printexc.raise_with_backtrace exn bt (* *) let[@inline never] rec transfer from scope = match Atomic.get from with | (Transferred | Borrowed) as case -> error case | Dropped -> check_released () | Resource r as before -> let into = Atomic.make Transferred in if Atomic.compare_and_set from before Transferred then begin Atomic.set into before; match Trigger.signal r.transferred_or_dropped; scope into with | result -> await_transferred_or_dropped into; result | exception exn -> let bt = Printexc.get_raw_backtrace () in drop into; Printexc.raise_with_backtrace exn bt end else transfer from scope (* *) let[@inline never] rec borrow instance scope = match Atomic.get instance with | (Transferred | Dropped | Borrowed) as case -> error case | Resource r as before -> if Atomic.compare_and_set instance before Borrowed then begin match scope r.resource with | result -> Atomic.set instance before; result | exception exn -> (* [Atomic.set] should not disturb the stack trace. *) Atomic.set instance before; raise exn end else borrow instance scope (* *) let[@inline never] rec move from scope = match Atomic.get from with | (Transferred | Borrowed) as case -> error case | Dropped -> check_released () | Resource r as before -> if Atomic.compare_and_set from before Transferred then begin match Trigger.signal r.transferred_or_dropped; scope r.resource with | result -> r.release r.resource; result | exception exn -> let bt = Printexc.get_raw_backtrace () in r.release r.resource; Printexc.raise_with_backtrace exn bt end else move from scope (* *) let[@inline never] finally release acquire scope = let x = acquire () in match scope x with | y -> release x; y | exception exn -> let bt = Printexc.get_raw_backtrace () in release x; Printexc.raise_with_backtrace exn bt external ( let@ ) : ('a -> 'b) -> 'a -> 'b = "%apply"
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>