@@ -29,13 +29,32 @@ import Nix.Utils ( bool
2929 , dup
3030 )
3131
32+
33+ -- * Data type @Deferred@
34+
35+ -- | Data is computed OR in a lazy thunk state which
36+ -- is still not evaluated.
3237data Deferred m v = Computed v | Deferred (m v )
3338 deriving (Functor , Foldable , Traversable )
3439
35- -- | It is a reference (@ref-tf: Ref m@), and as such also holds @Bool@ lock.
40+ -- ** Utils
41+
42+ -- | @Deferred (Computed|Deferred)@ analog of @either@.
43+ deferred :: (v -> b ) -> (m v -> b ) -> Deferred m v -> b
44+ deferred f1 f2 def =
45+ case def of
46+ Computed v -> f1 v
47+ Deferred action -> f2 action
48+ {-# inline deferred #-}
49+
50+
51+ -- * Thunk references & lock handling
52+
53+ -- | Thunk resource reference (@ref-tf: Ref m@), and as such also also hold
54+ -- a @Bool@ lock flag.
3655type ThunkRef m = (Var m Bool )
3756
38- -- | Reference (@ref-tf: Ref m v@) to a value that thunk holds.
57+ -- | Reference (@ref-tf: Ref m v@) to a value that the thunk holds.
3958type ThunkValueRef m v = Var m (Deferred m v )
4059
4160-- | @ref-tf@ lock instruction for @Ref m@ (@ThunkRef@).
@@ -46,6 +65,25 @@ lock = (True, )
4665unlock :: Bool -> (Bool , Bool )
4766unlock = (False , )
4867
68+ -- | Takes @ref-tf: Ref m@ reference, returns Bool result of the operation.
69+ lockThunk
70+ :: ( MonadBasicThunk m
71+ , MonadCatch m
72+ )
73+ => ThunkRef m
74+ -> m Bool
75+ lockThunk r = atomicModifyVar r lock
76+
77+ -- | Takes @ref-tf: Ref m@ reference, returns Bool result of the operation.
78+ unlockThunk
79+ :: ( MonadBasicThunk m
80+ , MonadCatch m
81+ )
82+ => ThunkRef m
83+ -> m Bool
84+ unlockThunk r = atomicModifyVar r unlock
85+
86+
4987-- * Data type for thunks: @NThunkF@
5088
5189-- | The type of very basic thunks
@@ -118,16 +156,16 @@ forceMain (Thunk n thunkRef thunkValRef) =
118156 pure
119157 (\ action ->
120158 do
121- lockedIt <- atomicModifyVar thunkRef lock
159+ lockedIt <- lockThunk thunkRef
122160 bool
123161 (throwM $ ThunkLoop $ show n)
124162 (do
125163 v <- catch action $ \ (e :: SomeException ) ->
126164 do
127- _unlockedIt <- atomicModifyVar thunkRef unlock
165+ _unlockedIt <- unlockThunk thunkRef
128166 throwM e
129167 writeVar thunkValRef (Computed v)
130- _unlockedIt <- atomicModifyVar thunkRef unlock
168+ _unlockedIt <- unlockThunk thunkRef
131169 pure v
132170 )
133171 (not lockedIt)
@@ -149,7 +187,7 @@ instance (MonadBasicThunk m, MonadCatch m)
149187 -> m r
150188 queryMF k n (Thunk _ thunkRef thunkValRef) =
151189 do
152- lockedIt <- atomicModifyVar thunkRef ( True , )
190+ lockedIt <- lockThunk thunkRef
153191 bool
154192 n
155193 go
@@ -163,7 +201,7 @@ instance (MonadBasicThunk m, MonadCatch m)
163201 k
164202 (const n)
165203 eres
166- _unlockedIt <- atomicModifyVar thunkRef ( False , )
204+ _unlockedIt <- unlockThunk thunkRef
167205 pure res
168206
169207 forceF
@@ -193,12 +231,3 @@ instance (MonadBasicThunk m, MonadCatch m)
193231 pure t
194232
195233
196- -- ** Utils
197-
198- -- | @either@ for @Deferred@ data type
199- deferred :: (v -> b ) -> (m v -> b ) -> Deferred m v -> b
200- deferred f1 f2 def =
201- case def of
202- Computed v -> f1 v
203- Deferred action -> f2 action
204- {-# inline deferred #-}
0 commit comments