
On Wed, 23 Apr 2008 15:54:15 +0100, Tim Harris (RESEARCH) wrote:
What do you think about a slight change:
readTVarWhen :: TVar a -> (a -> bool) -> STM a
This would retry until the (a->bool) function returns true (and, of course, as with a normal "retry", the implementation would need to watch all of the TVars that have been read).
This looks nice to me, anyway. I was confusing myself with my earlier reply. So basically you'd accumulate a list of reads to any given TVar and the old value that was read, and then walk through that list to determine whether to retry a transaction, where: 1. If the predicate fails on the new value, then keep waiting. 2. If the predicate succeeds on the new value: 2a. If the new value is the same as the old, look at next in list. 2b. If the new value is different from the old, retry now. Case 2a is there because the TVar may have been changed to something that fails the predicate, and then changed back to the original. Of course, retrying now is always legal, so you could simplify this by only keeping a record of the first access to the TVar and throwing away the old value; then always do 2b if the predicate succeeds. That would involve considerably less bookkeeping, at the expense of replaying some transactions unnecessarily. Then readTVarWhen would basically be special only if it's the first access to the TVar within the transaction. -- Chris Smith