@@ -76,11 +76,17 @@ type LazyTMVar m = Lazy.TMVar m
76
76
Strict TVar
77
77
-------------------------------------------------------------------------------}
78
78
79
+ #if CHECK_TVAR_INVARIANT
79
80
data StrictTVar m a = StrictTVar
80
81
{ invariant :: ! (a -> Maybe String )
81
82
-- ^ Invariant checked whenever updating the 'StrictTVar'.
82
83
, tvar :: ! (LazyTVar m a )
83
84
}
85
+ #else
86
+ newtype StrictTVar m a = StrictTVar
87
+ { tvar :: LazyTVar m a
88
+ }
89
+ #endif
84
90
85
91
labelTVar :: MonadLabelledSTM m => StrictTVar m a -> String -> STM m ()
86
92
labelTVar StrictTVar { tvar } = Lazy. labelTVar tvar
@@ -90,7 +96,8 @@ labelTVarIO v = atomically . labelTVar v
90
96
91
97
castStrictTVar :: LazyTVar m ~ LazyTVar n
92
98
=> StrictTVar m a -> StrictTVar n a
93
- castStrictTVar StrictTVar {invariant, tvar} = StrictTVar {invariant, tvar}
99
+ castStrictTVar v@ StrictTVar {tvar} =
100
+ mkStrictTVar (getInvariant v) tvar
94
101
95
102
-- | Get the underlying @TVar@
96
103
--
@@ -100,7 +107,8 @@ toLazyTVar :: StrictTVar m a -> LazyTVar m a
100
107
toLazyTVar StrictTVar { tvar } = tvar
101
108
102
109
newTVar :: MonadSTM m => a -> STM m (StrictTVar m a )
103
- newTVar ! a = StrictTVar (const Nothing ) <$> Lazy. newTVar a
110
+ newTVar ! a = (\ tvar -> mkStrictTVar (const Nothing ) tvar)
111
+ <$> Lazy. newTVar a
104
112
105
113
newTVarIO :: MonadSTM m => a -> m (StrictTVar m a )
106
114
newTVarIO = newTVarWithInvariantIO (const Nothing )
@@ -113,9 +121,10 @@ newTVarWithInvariantIO :: (MonadSTM m, HasCallStack)
113
121
=> (a -> Maybe String ) -- ^ Invariant (expect 'Nothing')
114
122
-> a
115
123
-> m (StrictTVar m a )
116
- newTVarWithInvariantIO invariant ! a =
117
- checkInvariant (invariant a) $
118
- StrictTVar invariant <$> Lazy. newTVarIO a
124
+ newTVarWithInvariantIO invariant ! a =
125
+ checkInvariant (invariant a) $
126
+ (\ tvar -> mkStrictTVar invariant tvar)
127
+ <$> Lazy. newTVarIO a
119
128
120
129
newTVarWithInvariantM :: (MonadSTM m , HasCallStack )
121
130
=> (a -> Maybe String ) -- ^ Invariant (expect 'Nothing')
@@ -131,9 +140,9 @@ readTVarIO :: MonadSTM m => StrictTVar m a -> m a
131
140
readTVarIO StrictTVar { tvar } = Lazy. readTVarIO tvar
132
141
133
142
writeTVar :: (MonadSTM m , HasCallStack ) => StrictTVar m a -> a -> STM m ()
134
- writeTVar StrictTVar { tvar, invariant } ! a =
135
- checkInvariant (invariant a) $
136
- Lazy. writeTVar tvar a
143
+ writeTVar v ! a =
144
+ checkInvariant (getInvariant v a) $
145
+ Lazy. writeTVar ( tvar v) a
137
146
138
147
modifyTVar :: MonadSTM m => StrictTVar m a -> (a -> a ) -> STM m ()
139
148
modifyTVar v f = readTVar v >>= writeTVar v . f
@@ -225,6 +234,9 @@ isEmptyTMVar (StrictTMVar tmvar) = Lazy.isEmptyTMVar tmvar
225
234
Dealing with invariants
226
235
-------------------------------------------------------------------------------}
227
236
237
+ getInvariant :: StrictTVar m a -> a -> Maybe String
238
+ mkStrictTVar :: (a -> Maybe String ) -> Lazy. TVar m a -> StrictTVar m a
239
+
228
240
-- | Check invariant (if enabled) before continuing
229
241
--
230
242
-- @checkInvariant mErr x@ is equal to @x@ if @mErr == Nothing@, and throws
@@ -234,9 +246,16 @@ isEmptyTMVar (StrictTMVar tmvar) = Lazy.isEmptyTMVar tmvar
234
246
-- invariants can reuse the same logic, rather than having to introduce new
235
247
-- per-package flags.
236
248
checkInvariant :: HasCallStack => Maybe String -> a -> a
249
+
237
250
#if CHECK_TVAR_INVARIANT
238
- checkInvariant Nothing k = k
239
- checkInvariant (Just err) _ = error $ " Invariant violation: " ++ err
251
+ getInvariant StrictTVar {invariant} = invariant
252
+ mkStrictTVar invariant tvar = StrictTVar {invariant, tvar}
253
+
254
+ checkInvariant Nothing k = k
255
+ checkInvariant (Just err) _ = error $ " Invariant violation: " ++ err
240
256
#else
241
- checkInvariant _err k = k
257
+ getInvariant _ = \ _ -> Nothing
258
+ mkStrictTVar _invariant tvar = StrictTVar {tvar}
259
+
260
+ checkInvariant _err k = k
242
261
#endif
0 commit comments