3 | import public Data.Pool.Internal
5 | import Control.Monad.Elin
6 | import Control.Monad.MCancel
8 | import Data.Array.Mutable
10 | import Data.Linear.Ref1
11 | import Data.Linear.Traverse1
13 | import Data.SortedSet
14 | import System.Concurrency
16 | import System.Posix.Timer
17 | import System.Posix.Timer.Prim
20 | %language ElabReflection
24 | %hide Data.List.Elem.get
32 | grabMonotonicTime : Elin World [Errno] (IClock CLOCK_MONOTONIC)
33 | grabMonotonicTime = getTime CLOCK_MONOTONIC
37 | grabRealTime : Elin World [Errno] (IClock CLOCK_REALTIME)
38 | grabRealTime = getTime CLOCK_REALTIME
45 | isCancelled _ QEnd =
47 | isCancelled x (QNode y ys) =
60 | appendQ (QNode y ys) x =
61 | QNode y (appendQ ys x)
75 | go (QNode x xs) acc =
85 | appendAll (QNode x xs) ys =
86 | QNode x (appendAll xs ys)
90 | normalize : Queue (Waiter a)
100 | dequeueLive : Queue (Waiter a)
102 | -> (Maybe (Waiter a), Queue (Waiter a), SortedSet Nat)
103 | dequeueLive QEnd cancelled =
104 | (Nothing, QEnd, cancelled)
105 | dequeueLive (QNode w@(MkWaiter id wake) rest) cancelled =
106 | let True = contains id cancelled
109 | (Just w, rest, cancelled)
112 | dequeueLive rest (delete id cancelled)
116 | dequeueStripe : Stripe a
117 | -> (Maybe (Waiter a), Stripe a)
118 | dequeueStripe (MkStripe available cache queue queuer nextid cancelled) =
119 | let fullq = normalize queue queuer
120 | (mw, rest, cancelled') = dequeueLive fullq cancelled
123 | (Nothing, MkStripe available cache QEnd QEnd nextid cancelled')
124 | in (Just w, MkStripe available cache rest QEnd nextid cancelled')
128 | isStale : Clock Duration
129 | -> IClock CLOCK_MONOTONIC
132 | isStale ttl now (MkEntry _ lastused) =
133 | timeDifference now lastused > ttl
145 | runEffects : (Nat, Stripe1 World a)
146 | -> List (StripeEffect a)
147 | -> F1 World (Either (List StripeError) ())
148 | runEffects (stripeid, (MkStripe1 striperef)) effects t =
149 | let effects' # t := traverse1 (runEffect (stripeid, (MkStripe1 striperef))) effects t
150 | effectserrs := concat $
lefts effects'
151 | in case effectserrs of
155 | Left effectserrs' # t
157 | runEffect : (Nat, Stripe1 World a)
159 | -> F1 World (Either (List StripeError) ())
160 | runEffect _ None t =
162 | runEffect _ (Wake ch val) t =
163 | let () # t := ioToF1 (channelPut ch val) t
165 | runEffect _ (WakeMany pairs) t =
166 | let () # t := traverse1_ (\(ch,val) => ioToF1 (channelPut ch val)) pairs t
168 | runEffect _ (FreeMany free xs) t =
169 | let () # t := traverse1_ (\x => ioToF1 (free x)) xs t
171 | runEffect (stripeid, (MkStripe1 striperef)) (InsertWithTimestamp val) t =
172 | let monotonicnow # t := ioToF1 (runElinIO grabMonotonicTime) t
173 | in case monotonicnow of
174 | Left monotonicnowerr =>
175 | let realtimenow # t := ioToF1 (runElinIO grabRealTime) t
176 | Right realtimenow' := realtimenow
177 | | Left realtimenowerr =>
178 | Left [ MkStripeError stripeid "Data.Pool.runEffects.runEffect" (show monotonicnowerr) Nothing
179 | , MkStripeError stripeid "Data.Pool.runEffects.runEffect" (show realtimenowerr) Nothing
181 | in Left [MkStripeError stripeid "Data.Pool.runEffects.runEffect" (show monotonicnowerr) (Just realtimenow')] # t
182 | Right monotonicnow' =>
183 | let entry := MkEntry val monotonicnow'
184 | () # t := casupdate1 striperef (\(MkStripe available cache queue queuer nextid cancelled) =>
185 | (MkStripe available (entry :: cache) queue queuer nextid cancelled, ())
211 | casWithEffects : (Nat, Stripe1 World a)
212 | -> (Stripe a -> StripeStep a)
213 | -> F1 World (Either (List StripeError) ())
214 | casWithEffects (stripeid, (MkStripe1 striperef)) stepfn t =
215 | let effects # t := casupdate1 striperef (\stripe =>
216 | let (MkStripeStep stripe' stripeeffects) = stepfn stripe
217 | in (stripe', stripeeffects)
219 | in runEffects (stripeid, (MkStripe1 striperef)) effects t
227 | setNumStripes : (pc : PoolConfig a)
228 | -> (
n ** (LTE 1 n, LTE n (fst (poolmaxresources pc))))
230 | setNumStripes (MkPoolConfig create free cachettl (
maxres ** prfmaxres)
_ pclabel) numstripes =
231 | MkPoolConfig create
234 | (
maxres ** prfmaxres)
240 | setPoolLabel : String
243 | setPoolLabel label pc =
244 | { poolconfiglabel := label } pc
310 | newPool : (numstripes : Nat)
312 | -> F1 World (Either (List Pool1Error) (Pool1 World numstripes a))
313 | newPool numstripes pc@(MkPoolConfig create free cachettl (
maxres ** prfmaxres)
_ pclabel) t =
314 | let striperesources := let base = div maxres numstripes
315 | rest = mod maxres numstripes
316 | in zip (range Z numstripes)
317 | (distribute base rest numstripes)
318 | pools # t := unsafeMArray1 numstripes t
319 | pools' # t := saturateLocalPools 0 numstripes striperesources pools t
323 | in Right (MkPool1 pc pools) # t
330 | range start (S k) =
331 | start :: range (S start) k
336 | distribute base rest Z =
338 | distribute base Z (S k) =
339 | base :: distribute base Z k
340 | distribute base (S r) (S k) =
341 | (S base) :: distribute base r k
342 | saturateLocalPools : (o, x : Nat)
343 | -> {auto v : Ix x numstripes}
344 | -> {auto 0 prf : LTE o $
ixToNat v}
345 | -> (resources : List (Nat, Nat))
346 | -> (arr : MArray World numstripes (LocalPool1 World a))
347 | -> F1 World (Either (List Pool1Error) ())
348 | saturateLocalPools o Z _ _ t =
350 | saturateLocalPools o (S j) resources arr t =
351 | case lookup j resources of
353 | let realtimenow # t := ioToF1 (runElinIO grabRealTime) t
354 | Right realtimenow' := realtimenow
355 | | Left realtimenowerr =>
356 | let newerrors := [ MkPool1Error "Data.Pool.newPool.saturatePools" (show realtimenowerr) Nothing
357 | , MkPool1Error "Data.Pool.newPool.saturatePools" "impossible index" Nothing
359 | in Left newerrors # t
360 | newerrors := [MkPool1Error "Data.Pool.newPool.saturatePools" "impossible index" (Just realtimenow')]
361 | in Left newerrors # t
363 | let striperef # t := ref1 ( MkStripe resource
370 | striperef1 := MkStripe1 striperef
371 | localpool := MkLocalPool1 j striperef1
372 | Just j' := tryNatToFin j
374 | let realtimenow # t := ioToF1 (runElinIO grabRealTime) t
375 | Right realtimenow' := realtimenow
376 | | Left realtimenowerr =>
377 | let newerrors := [ MkPool1Error "Data.Pool.newPool.saturatePools" (show realtimenowerr) Nothing
378 | , MkPool1Error "Data.Pool.newPool.saturatePools" "couldn't convert Nat to Fin" Nothing
380 | in Left newerrors # t
381 | newerrors := [MkPool1Error "Data.Pool.newPool.saturatePools" "couldn't convert Nat to Fin" (Just realtimenow')]
382 | in Left newerrors # t
383 | () # t := set arr j' localpool t
384 | in saturateLocalPools o j resources arr t
454 | getLocalPool : {n : Nat}
456 | -> F1 World (Either (List Pool1Error) (LocalPool1 World a))
457 | getLocalPool pool@(MkPool1 _ localpools) t =
461 | sid' := remInt sid (cast {to=Int} n)
464 | let realtimenow # t := ioToF1 (runElinIO grabRealTime) t
465 | Right realtimenow' := realtimenow
466 | | Left realtimenowerr =>
467 | let newerrors := [ MkPool1Error "Data.Pool.getLocalPool" (show realtimenowerr) Nothing
468 | , MkPool1Error "Data.Pool.getLocalPool" "division by zero" Nothing
470 | in Left newerrors # t
471 | newerrors := [MkPool1Error "Data.Pool.getLocalPool" "division by zero" (Just realtimenow')]
472 | in Left newerrors # t
473 | Just sid''' := tryNatToFin (cast {to=Nat} sid'')
475 | let realtimenow # t := ioToF1 (runElinIO grabRealTime) t
476 | Right realtimenow' := realtimenow
477 | | Left realtimenowerr =>
478 | let newerrors := [ MkPool1Error "Data.Pool.getLocalPool" (show realtimenowerr) Nothing
479 | , MkPool1Error "Data.Pool.getLocalPool" "couldn't convert Nat to Fin" Nothing
481 | in Left newerrors # t
482 | newerrors := [MkPool1Error "Data.Pool.getLocalPool" "couldn't convert Nat to Fin" (Just realtimenow')]
483 | in Left newerrors # t
484 | sid'''' # t := get localpools sid''' t
485 | in Right sid'''' # t
487 | let sid # t := ioToF1 getThreadId t
488 | sid' := remInt sid (cast {to=Int} n)
491 | let realtimenow # t := ioToF1 (runElinIO grabRealTime) t
492 | Right realtimenow' := realtimenow
493 | | Left realtimenowerr =>
494 | let newerrors := [ MkPool1Error "Data.Pool.getLocalPool" (show realtimenowerr) Nothing
495 | , MkPool1Error "Data.Pool.getLocalPool" "division by zero" Nothing
497 | in Left newerrors # t
498 | newerrors := [MkPool1Error "Data.Pool.getLocalPool" "division by zero" (Just realtimenow')]
499 | in Left newerrors # t
500 | Just sid''' := tryNatToFin (cast {to=Nat} sid'')
502 | let realtimenow # t := ioToF1 (runElinIO grabRealTime) t
503 | Right realtimenow' := realtimenow
504 | | Left realtimenowerr =>
505 | let newerrors := [ MkPool1Error "Data.Pool.getLocalPool" (show realtimenowerr) Nothing
506 | , MkPool1Error "Data.Pool.getLocalPool" "couldn't convert Nat to Fin" Nothing
508 | in Left newerrors # t
509 | newerrors := [MkPool1Error "Data.Pool.getLocalPool" "couldn't convert Nat to Fin" (Just realtimenow')]
510 | in Left newerrors # t
511 | sid'''' # t := get localpools sid''' t
512 | in Right sid'''' # t
530 | False = (r /= 0) && (signumInt x /= signumInt y)
541 | in Just $
x - (quotInt x y) * y
558 | signal stripe@(MkStripe available cache queue queuer nextid cancelled) result =
559 | let (mw, MkStripe available' cache' queue' queuer' nextid' cancelled') = dequeueStripe stripe
560 | Just (MkWaiter _ wake) = mw
564 | MkStripeStep (MkStripe (S available') cache' queue' queuer' nextid' cancelled')
565 | [InsertWithTimestamp val]
567 | MkStripeStep (MkStripe available' cache' queue' queuer' nextid' cancelled')
570 | MkStripeStep (MkStripe available' cache' queue' queuer' nextid' cancelled')
572 | in MkStripeStep (MkStripe available' cache' queue' queuer' nextid' cancelled')
609 | waitForResource : (Nat, Stripe1 World a)
611 | -> Channel (WakeResult a)
612 | -> F1 World (Either (List StripeError) (WakeResult a))
613 | waitForResource (stripeid, (MkStripe1 striperef)) wid wake t =
614 | let res # t := ioToF1 (runElinIO (waitForResource' (MkStripe1 striperef) wid wake)) t
617 | let realtimenow # t := ioToF1 (runElinIO grabRealTime) t
618 | Right realtimenow' := realtimenow
619 | | Left realtimenowerr =>
620 | let newerrors := [ MkStripeError stripeid "Data.Pool.waitForResource" (show realtimenowerr) Nothing
621 | , MkStripeError stripeid "Data.Pool.waitForResource" (show err) Nothing
623 | in Left newerrors # t
624 | newerrors := [MkStripeError stripeid "Data.Pool.waitForResource" (show err) (Just realtimenow')]
625 | in Left newerrors # t
628 | cleanup : Stripe1 World a
631 | cleanup (MkStripe1 mstripe) wid t =
632 | casupdate1 mstripe (\(MkStripe available cache queue queuer nextid cancelled) =>
633 | (MkStripe available cache queue queuer nextid (insert wid cancelled), ())
635 | waitForResource'' : Channel (WakeResult a)
636 | -> F1 World (WakeResult a)
637 | waitForResource'' wake t =
638 | ioToF1 (channelGet wake) t
639 | waitForResource' : MCancel (Elin World)
642 | -> Channel (WakeResult a)
643 | -> Elin World [Errno] (WakeResult a)
644 | waitForResource' mstripe wid wake =
645 | onAbort (runIO (waitForResource'' wake)) (runIO (cleanup mstripe wid))
658 | destroyResource : (Nat, Stripe1 World a)
659 | -> F1 World (Either (List StripeError) ())
660 | destroyResource (stripeid, (MkStripe1 striperef)) t =
661 | let res # t := ioToF1 (runElinIO (destroy (stripeid, (MkStripe1 striperef)))) t
664 | let realtimenow # t := ioToF1 (runElinIO grabRealTime) t
665 | Right realtimenow' := realtimenow
666 | | Left realtimenowerr =>
667 | let newerrors := [ MkStripeError stripeid "Data.Pool.destroyResource" (show realtimenowerr) Nothing
668 | , MkStripeError stripeid "Data.Pool.destoryResource" (show err) Nothing
670 | in Left newerrors # t
671 | newerrors := [MkStripeError stripeid "Data.Pool.destroyResource" (show err) (Just realtimenow')]
672 | in Left newerrors # t
678 | destroy' : (Nat, Stripe1 World a)
679 | -> F1 World (Either (List StripeError) ())
680 | destroy' (stripeid, (MkStripe1 striperef)) t =
681 | casWithEffects (stripeid, (MkStripe1 striperef)) (\stripe => signal stripe Create) t
682 | destroy : MCancel (Elin World)
683 | => (Nat, Stripe1 World a)
684 | -> Elin World [Errno] (Either (List StripeError) ())
685 | destroy (stripeid, (MkStripe1 striperef)) =
686 | uncancelable $
\_ =>
687 | runIO (destroy' (stripeid, (MkStripe1 striperef)))
702 | cleanStripe : (Entry a -> Bool)
704 | -> (Nat, Stripe1 World a)
705 | -> F1 World (Either (List StripeError) ())
706 | cleanStripe isstale free (stripeid, (MkStripe1 striperef)) t =
707 | let res # t := ioToF1 (runElinIO (cleanStripe' (stripeid, (MkStripe1 striperef)))) t
710 | let realtimenow # t := ioToF1 (runElinIO grabRealTime) t
711 | Right realtimenow' := realtimenow
712 | | Left realtimenowerr =>
713 | let newerrors := [ MkStripeError stripeid "Data.Pool.cleanStripe" (show realtimenowerr) Nothing
714 | , MkStripeError stripeid "Data.Pool.cleanStripe" (show err) Nothing
716 | in Left newerrors # t
717 | newerrors := [MkStripeError stripeid "Data.Pool.cleanStripe" (show err) (Just realtimenow')]
718 | in Left newerrors # t
726 | step (MkStripe available cache queue queuer nextid cancelled) =
727 | let (stale, fresh) = partition isstale cache
728 | freedvals = map (\(MkEntry v _) => v) stale
730 | (MkStripe available fresh queue queuer nextid cancelled)
731 | ( case freedvals of
737 | cleanStripe'' : (Nat, Stripe1 World a)
738 | -> F1 World (Either (List StripeError) ())
739 | cleanStripe'' (stripeid, (MkStripe1 striperef)) t =
740 | casWithEffects (stripeid, (MkStripe1 striperef)) step t
741 | cleanStripe' : MCancel (Elin World)
742 | => (Nat, Stripe1 World a)
743 | -> Elin World [Errno] (Either (List StripeError) ())
744 | cleanStripe' (stripeid, (MkStripe1 striperef)) =
745 | uncancelable $
\_ =>
746 | runIO (cleanStripe'' (stripeid, (MkStripe1 striperef)))
812 | cleanStripeIfNeeded : (ttl : Clock Duration)
813 | -> (free : a -> IO ())
814 | -> (Nat, Stripe1 World a)
815 | -> F1 World (Either (List StripeError) ())
816 | cleanStripeIfNeeded ttl free (stripeid, (MkStripe1 striperef)) t =
817 | let now # t := ioToF1 (runElinIO grabMonotonicTime) t
820 | let realtimenow # t := ioToF1 (runElinIO grabRealTime) t
821 | Right realtimenow' := realtimenow
822 | | Left realtimenowerr =>
823 | let newerrors := [ MkStripeError stripeid "Data.Pool.cleanStripeIfNeeded" (show realtimenowerr) Nothing
824 | , MkStripeError stripeid "Data.Pool.cleanStripeIfNeeded" (show err) Nothing
826 | in Left newerrors # t
827 | newerrors := [MkStripeError stripeid "Data.Pool.cleanStripeIfNeeded" (show err) (Just realtimenow')]
828 | in Left newerrors # t
829 | in cleanStripe (isStale ttl now') free (stripeid, (MkStripe1 striperef)) t
842 | putResource : Pool1 World n a
843 | -> (Nat, Stripe1 World a)
845 | -> F1 World (Either (List StripeError) ())
846 | putResource (MkPool1 (MkPoolConfig _ free ttl _ _ _) _) (stripeid, (MkStripe1 striperef)) val t =
847 | let stripecleanerrs # t := cleanStripeIfNeeded ttl free (stripeid, (MkStripe1 striperef)) t
848 | in casWithEffects (stripeid, (MkStripe1 striperef)) (\stripe => signal stripe (Deliver val)) t
867 | destroyAllResources : {n : Nat}
869 | -> MArray World n (LocalPool1 World a)
870 | -> F1 World (Either (List StripeError) ())
871 | destroyAllResources (MkPool1 (MkPoolConfig _ freeresource _ _ _ _) _) localpools t =
872 | go 0 n localpools t
875 | -> {auto v : Ix x n}
876 | -> {auto 0 prf : LTE o $
ixToNat v}
877 | -> (arr : MArray World n (LocalPool1 World a))
878 | -> F1 World (Either (List StripeError) ())
882 | let MkLocalPool1 stripeid stripe1 # t := getIx arr j t
883 | cleanedstripe # t := cleanStripe (const True) freeresource (stripeid, stripe1) t
884 | Right () := cleanedstripe
904 | restoreSize : (Nat, Stripe1 World a)
905 | -> F1 World (Either (List StripeError) ())
906 | restoreSize (stripeid, (MkStripe1 striperef)) t =
907 | casWithEffects (stripeid, (MkStripe1 striperef)) step t
911 | step (MkStripe available cache queue queuer nextid cancelled) =
913 | (MkStripe (S available) cache queue queuer nextid cancelled)
969 | takeResource : {n : Nat}
971 | -> F1 World (Either (Either (List Pool1Error) (List StripeError)) (a, LocalPool1 World a))
972 | takeResource pool@(MkPool1 poolconfig@(MkPoolConfig _ free ttl _ _ _) localpools) t =
973 | let lp # t := getLocalPool pool t
974 | Right lp'@(MkLocalPool1 stripeid stripe1@(MkStripe1 striperef)) := lp
976 | Left (Left errs) # t
977 | cleanedstripe # t := cleanStripeIfNeeded ttl free (stripeid, (MkStripe1 striperef)) t
978 | Right () := cleanedstripe
980 | Left (Right errs) # t
981 | wake # t := ioToF1 makeChannel t
982 | res : (List (StripeEffect a), Either a (Either () (Nat, Channel (WakeResult a))))
983 | (effects, res'') # t :=
984 | casupdate1 striperef (\(MkStripe available cache queue queuer nextid cancelled) =>
987 | MkEntry v _ :: rest =>
988 | let none : List (StripeEffect a)
990 | stripe' = MkStripe available
996 | result : Either a (Either () (Nat, Channel (WakeResult a)))
1006 | let none : List (StripeEffect a)
1010 | waiter = MkWaiter wid wake
1011 | stripe' = MkStripe available
1014 | (appendQ queuer waiter)
1017 | result : Either a (Either () (Nat, Channel (WakeResult a)))
1018 | result = Right (Right (wid, wake))
1024 | let none : List (StripeEffect a)
1026 | stripe' = MkStripe (minus available 1)
1032 | result : Either a (Either () (Nat, Channel (WakeResult a)))
1033 | result = Right (Left ())
1039 | effects' # t := runEffects (stripeid, stripe1) effects t
1043 | Right (Right (wid, wake)) := res''
1049 | let res # t := ioToF1 (runElinIO (createWithCleanup poolconfig (stripeid, stripe1))) t
1053 | realtimenow # t := ioToF1 (runElinIO grabRealTime) t
1054 | Right realtimenow' := realtimenow
1055 | | Left realtimenowerr =>
1056 | let newerrors := [ MkStripeError stripeid "Data.Pool.takeResource" (show realtimenowerr) Nothing
1057 | , MkStripeError stripeid "Data.Pool.takeResource" (show err) Nothing
1059 | in Left (Right newerrors) # t
1060 | newerrors := [MkStripeError stripeid "Data.Pool.takeResource" (show err) (Just realtimenow')]
1061 | in Left (Right newerrors) # t
1062 | wakeresult # t := waitForResource (stripeid, stripe1) wid wake t
1063 | Right wakeresult' := wakeresult
1065 | let realtimenow # t := ioToF1 (runElinIO grabRealTime) t
1066 | Right realtimenow' := realtimenow
1067 | | Left realtimenowerr =>
1068 | let newerrors := [ MkStripeError stripeid "Data.Pool.takeResource" (show realtimenowerr) Nothing
1069 | , MkStripeError stripeid "Data.Pool.takeResource" "Data.Pool.waitForResource failed" Nothing
1071 | in Left (Right $
errs ++ newerrors) # t
1072 | newerrors := [MkStripeError stripeid "Data.Pool.takeResource" "Data.Pool.waitForResource failed" (Just realtimenow')]
1073 | in Left (Right $
errs ++ newerrors) # t
1080 | let realtimenow # t := ioToF1 (runElinIO grabRealTime) t
1081 | Right realtimenow' := realtimenow
1082 | | Left realtimenowerr =>
1083 | let newerrors := [ MkStripeError stripeid "Data.Pool.takeResource" (show realtimenowerr) Nothing
1084 | , MkStripeError stripeid "Data.Pool.takeResource" "impossible" Nothing
1086 | in Left (Right newerrors) # t
1087 | newerrors := [MkStripeError stripeid "Data.Pool.takeResource" "impossible" (Just realtimenow')]
1088 | in Left (Right newerrors) # t
1089 | res # t := ioToF1 (runElinIO (createWithCleanup poolconfig (stripeid, stripe1))) t
1093 | realtimenow # t := ioToF1 (runElinIO grabRealTime) t
1094 | Right realtimenow' := realtimenow
1095 | | Left realtimenowerr =>
1096 | let newerrors := [ MkStripeError stripeid "Data.Pool.takeResource" (show realtimenowerr) Nothing
1097 | , MkStripeError stripeid "Data.Pool.takeResource" (show err) Nothing
1099 | in Left (Right newerrors) # t
1100 | newerrors := [MkStripeError stripeid "Data.Pool.takeResource" (show err) (Just realtimenow')]
1101 | in Left (Right newerrors) # t
1103 | createWithCleanup : PoolConfig a
1104 | -> (Nat, Stripe1 World a)
1105 | -> Elin World [Errno] a
1106 | createWithCleanup (MkPoolConfig createResource _ _ _ _ _) (stripeid, stripe) =
1107 | onAbort (liftIO createResource) ( do _ <- runIO (restoreSize (stripeid, stripe))
1152 | withResource : {n : Nat}
1155 | -> F1 World (Either (Either (List Pool1Error) (List StripeError)) (Maybe r))
1156 | withResource pool@(MkPool1 _ localpools) f t =
1157 | let res # t := ioToF1 (runElinIO (withResource' pool f)) t
1160 | let realtimenow # t := ioToF1 (runElinIO grabRealTime) t
1161 | Right realtimenow' := realtimenow
1162 | | Left realtimenowerr =>
1163 | let newerrors := [ MkPool1Error "Data.Pool.withResource" (show realtimenowerr) Nothing
1164 | , MkPool1Error "Data.Pool.withResource" (show err) Nothing
1166 | in Left (Left newerrors) # t
1167 | newerrors := [MkPool1Error "Data.Pool.withResource" (show err) (Just realtimenow')]
1168 | in Left (Left newerrors) # t
1171 | let Right stripeerrs := errs
1173 | Left (Left poolerrs) # t
1174 | in Left (Right stripeerrs) # t
1178 | in Right (Just res''') # t
1180 | withResource' : {n : Nat}
1181 | -> MCancel (Elin World)
1184 | -> Elin World [Errno] (Either (Either (List Pool1Error) (List StripeError)) (Maybe r))
1185 | withResource' pool@(MkPool1 _ localpools) f =
1186 | uncancelable $
\poll => do
1187 | res <- runIO (takeResource pool)
1188 | let Right (res', MkLocalPool1 stripeid (MkStripe1 striperef)) = res
1190 | let Right stripeerrs = errs
1192 | pure (Left (Left poolerrs))
1193 | pure (Left (Right stripeerrs))
1194 | res'' <- onAbort (poll $
liftIO $
f res') ( do _ <- runIO (destroyResource (stripeid, (MkStripe1 striperef)))
1197 | putr <- runIO (putResource pool (stripeid, (MkStripe1 striperef)) res')
1200 | pure (Left (Right errs))
1201 | pure (Right (Just res''))
1223 | tryTakeResource : {n : Nat}
1225 | -> F1 World (Either (Either (List Pool1Error) (List StripeError)) (Maybe (a, LocalPool1 World a)))
1226 | tryTakeResource pool@(MkPool1 _ localpools) t =
1227 | let res # t := ioToF1 (runElinIO (tryTakeResource' pool)) t
1230 | let realtimenow # t := ioToF1 (runElinIO grabRealTime) t
1231 | Right realtimenow' := realtimenow
1232 | | Left realtimenowerr =>
1233 | let newerrors := [ MkPool1Error "Data.Pool.tryTakeResource" (show realtimenowerr) Nothing
1234 | , MkPool1Error "Data.Pool.tryTakeResource" (show err) Nothing
1236 | in Left (Left newerrors) # t
1237 | newerrors := [MkPool1Error "Data.Pool.tryTakeResource" (show err) (Just realtimenow')]
1238 | in Left (Left newerrors) # t
1241 | let Right stripeerrs := errs
1243 | Left (Left poolerrs) # t
1244 | in Left (Right stripeerrs) # t
1248 | in Right (Just res''') # t
1250 | tryTakeResource'' : {n : Nat}
1251 | -> MCancel (Elin World)
1253 | -> F1 World (Either (Either (List Pool1Error) (List StripeError)) (Maybe (a, LocalPool1 World a)))
1254 | tryTakeResource'' pool@(MkPool1 (MkPoolConfig _ free ttl _ _ _) _) t =
1255 | let lp # t := getLocalPool pool t
1256 | Right lp'@(MkLocalPool1 stripeid stripe1@(MkStripe1 striperef)) := lp
1258 | Left (Left poolerrs) # t
1260 | cleanedstripe # t := cleanStripeIfNeeded ttl free (stripeid, (MkStripe1 striperef)) t
1261 | Right () := cleanedstripe
1263 | Left (Right stripeerrs) # t
1266 | casupdate1 striperef (\(MkStripe available cache queue queuer nextid cancelled) =>
1267 | case (available == 0, cache) of
1270 | ( MkStripe available cache queue queuer nextid cancelled
1274 | (False, MkEntry v _ :: rest) =>
1285 | ( MkStripe available cache queue queuer nextid cancelled
1292 | in Right (Just (v, lp')) # t
1293 | tryTakeResource' : {n : Nat}
1294 | -> MCancel (Elin World)
1296 | -> Elin World [Errno] (Either (Either (List Pool1Error) (List StripeError)) (Maybe (a, LocalPool1 World a)))
1297 | tryTakeResource' pool =
1299 | runIO (tryTakeResource'' pool)
1346 | tryWithResource : {n : Nat}
1349 | -> F1 World (Either (Either (List Pool1Error) (List StripeError)) (Maybe r))
1350 | tryWithResource pool@(MkPool1 _ localpools) f t =
1351 | let res # t := ioToF1 (runElinIO (tryWithResource' pool f)) t
1354 | let realtimenow # t := ioToF1 (runElinIO grabRealTime) t
1355 | Right realtimenow' := realtimenow
1356 | | Left realtimenowerr =>
1357 | let newerrors := [ MkPool1Error "Data.Pool.tryWithResource" (show realtimenowerr) Nothing
1358 | , MkPool1Error "Data.Pool.tryWithResource" (show err) Nothing
1360 | in Left (Left newerrors) # t
1361 | newerrors := [MkPool1Error "Data.Pool.tryWithResource" (show err) (Just realtimenow')]
1362 | in Left (Left newerrors) # t
1365 | let Right stripeerrs := errs
1367 | Left (Left poolerrs) # t
1368 | in Left (Right stripeerrs) # t
1372 | in Right (Just res''') # t
1374 | tryWithResource' : {n : Nat}
1375 | -> MCancel (Elin World)
1378 | -> Elin World [Errno] (Either (Either (List Pool1Error) (List StripeError)) (Maybe r))
1379 | tryWithResource' pool@(MkPool1 _ localpools) f =
1380 | uncancelable $
\poll => do
1381 | res <- runIO (tryTakeResource pool)
1384 | let Right stripeerrs := errs
1386 | pure (Left (Left poolerrs))
1387 | in pure (Left (Right stripeerrs))
1388 | let Just (res'', MkLocalPool1 stripeid (MkStripe1 striperef)) := res'
1391 | res''' <- onAbort (poll $
liftIO $
f res'') ( do _ <- runIO (destroyResource (stripeid, (MkStripe1 striperef)))
1394 | putr <- runIO (putResource pool (stripeid, (MkStripe1 striperef)) res'')
1397 | pure (Left (Right stripeerrs))
1398 | pure (Right (Just res'''))