Revision 32935f7a

b/src/Ganeti/Locking/Waiting.hs
118 118
-- the owners to be notified. The type is chosen to be suitable as fold
119 119
-- operation.
120 120
--
121
-- This function calls the later defined updateLocksWaiting, as they are
121
-- This function calls the later defined updateLocksWaiting', as they are
122 122
-- mutually recursive.
123 123
tryFulfillRequest :: (Lock a, Ord b, Ord c)
124 124
                  => (LockWaiting a b c, S.Set b)
125 125
                  -> (c, b, [L.LockRequest a])
126 126
                  -> (LockWaiting a b c, S.Set b)
127 127
tryFulfillRequest (waiting, toNotify) (prio, owner, req) =
128
  let (waiting', (_, newNotify)) = updateLocksWaiting prio owner req waiting
128
  let (waiting', (_, newNotify)) = updateLocksWaiting' prio owner req waiting
129 129
  in (waiting', toNotify `S.union` newNotify)
130 130

  
131 131
-- | Internal function to recursively follow the consequences of a change.
......
156 156
-- | Update the locks on an onwer according to the given request, if possible.
157 157
-- Additionally (if the request succeeds) fulfill any pending requests that
158 158
-- became possible through this request. Return the new state of the waiting
159
-- structure, the result of the operation, and a list of nodes to be notified
160
-- that their locks are available now. The result is, as for lock allocation,
161
-- the set of owners the request is blocked on. Again, the type is chosen to be
162
-- suitable for use in atomicModifyIORef.
163
updateLocks :: (Lock a, Ord b, Ord c)
164
            => b
165
            -> [L.LockRequest a]
166
            -> LockWaiting a b c
167
            -> (LockWaiting a b c, (Result (S.Set b), S.Set b))
168
updateLocks owner reqs state =
159
-- structure, the result of the operation, and a list of owner whose requests
160
-- have been fulfilled. The result is, as for lock allocation, the set of owners
161
-- the request is blocked on. Again, the type is chosen to be suitable for use
162
-- in atomicModifyIORef.
163
updateLocks' :: (Lock a, Ord b, Ord c)
164
             => b
165
             -> [L.LockRequest a]
166
             -> LockWaiting a b c
167
             -> (LockWaiting a b c, (Result (S.Set b), S.Set b))
168
updateLocks' owner reqs state =
169 169
  let (allocation', result) = L.updateLocks owner reqs (lwAllocation state)
170 170
      state' = state { lwAllocation = allocation' }
171 171
      (notify, state'') = revisitRequests S.empty (S.singleton owner) state'
......
184 184
-- | Update locks as soon as possible. If the request cannot be fulfilled
185 185
-- immediately add the request to the waiting queue. The first argument is
186 186
-- the priority at which the owner is waiting, the remaining are as for
187
-- updateLocks, and so is the output.
188
updateLocksWaiting :: (Lock a, Ord b, Ord c)
189
                   => c
190
                   -> b
191
                   -> [L.LockRequest a]
192
                   -> LockWaiting a b c
193
                   -> (LockWaiting a b c, (Result (S.Set b), S.Set b))
194
updateLocksWaiting prio owner reqs state =
195
  let (state', (result, notify)) = updateLocks owner reqs state
187
-- updateLocks', and so is the output.
188
updateLocksWaiting' :: (Lock a, Ord b, Ord c)
189
                    => c
190
                    -> b
191
                    -> [L.LockRequest a]
192
                    -> LockWaiting a b c
193
                    -> (LockWaiting a b c, (Result (S.Set b), S.Set b))
194
updateLocksWaiting' prio owner reqs state =
195
  let (state', (result, notify)) = updateLocks' owner reqs state
196 196
      state'' = case result of
197 197
        Bad _ -> state' -- bad requests cannot be queued
198 198
        Ok empty | S.null empty -> state'
......
210 210
                                }
211 211
  in (state'', (result, notify))
212 212

  
213
-- | Update the locks on an onwer according to the given request, if possible.
214
-- Additionally (if the request succeeds) fulfill any pending requests that
215
-- became possible through this request. Return the new state of the waiting
216
-- structure, the result of the operation, and a list of owners to be notified.
217
-- The result is, as for lock allocation, the set of owners the request is
218
-- blocked on. Again, the type is chosen to be suitable for use in
219
-- atomicModifyIORef.
220
updateLocks :: (Lock a, Ord b, Ord c)
221
            => b
222
            -> [L.LockRequest a]
223
            -> LockWaiting a b c
224
            -> (LockWaiting a b c, (Result (S.Set b), S.Set b))
225
updateLocks owner req state =
226
  second (second $ S.delete owner) $ updateLocks' owner req state
227

  
228
-- | Update locks as soon as possible. If the request cannot be fulfilled
229
-- immediately add the request to the waiting queue. The first argument is
230
-- the priority at which the owner is waiting, the remaining are as for
231
-- updateLocks, and so is the output.
232
updateLocksWaiting :: (Lock a, Ord b, Ord c)
233
                   => c
234
                   -> b
235
                   -> [L.LockRequest a]
236
                   -> LockWaiting a b c
237
                   -> (LockWaiting a b c, (Result (S.Set b), S.Set b))
238
updateLocksWaiting prio owner req state =
239
  second (second $ S.delete owner) $ updateLocksWaiting' prio owner req state
240

  
213 241
-- | Compute the state of a waiting after an owner gives up
214 242
-- on his pending request.
215 243
removePendingRequest :: (Lock a, Ord b, Ord c)

Also available in: Unified diff