
On 27/04/2012 15:58, Antoine Latter wrote:
On Fri, Apr 27, 2012 at 5:24 AM, Simon Marlow
wrote: On 17/04/2012 15:56, Edward Kmett wrote:
Using the newUniqueSTM approach, while it fixes the issue of obtaining Uniques from STM will still mean that there is no way to unsafePerformIO or unsafeInterleaveIO anything that would get you a newUnique without forking a whole thread, and getting it atomically there, no?
That concern was why the discussion last time had turned toward reverting to the previous IORef version, which is safe under a wider array of conditions.
So the options are:
1. Use STM; provide newUniqueSTM; newUnique will not work inside unsafePerformIO
2. Use atomicModifyIORef; no way to generate uniques in STM
3. Use atomicModifyIORef; provide a separate STM version; Uniques generated by newUnique and newUniqueSTM might clash
With this one, couldn't you divide the value space between the two? The IORef could get the even uniques, the TVar the odd?
That's a good idea.
What would you like to do? None of the options are perfect.
Hmm, thinking aloud here, I suppose it *might* be possible to add
atomicModifyTVar :: TVar a -> (a -> (a,b)) -> IO b
that would not use a full transaction internally, and would work inside unsafePerformIO.
Urk. What would it do inside a transaction, where the transaction creates a new unique with the STM API?
I presume you mean if it was called inside unsafePerformIO inside a transaction: then it would cause the enclosing transaction to abort at commit time. So you could shoot yourself in the foot by writing a transaction that called out to a library that happened to use unsafePerformIO.newUnique internally. So I retract my wild and crazy suggestion :-) Cheers, Simon
I don't know much about STM internals, so maybe it's easy to have 'atomicModifyTVar' sometimes latch onto the lexical transaction and sometimes not.