Is this a concurrency bug in base?
Jean-Marie Gaillourdet
jmg at gaillourdet.net
Sun Oct 9 17:51:06 CEST 2011
Hi,
On 09.10.2011, at 17:37, Jean-Marie Gaillourdet wrote:
> Hi,
>
> On 09.10.2011, at 17:27, Daniel Fischer wrote:
>
>> That's what I expect.
>> I think what happens is:
>>
>> -- from Data.Typeable
>>
>> cache = unsafePerformIO $ ...
>>
>>
>> mkTyConKey :: String -> Key
>> mkTyConKey str
>> = unsafePerformIO $ do
>> let Cache {next_key = kloc, tc_tbl = tbl} = cache
>> mb_k <- HT.lookup tbl str
>> case mb_k of
>> Just k -> return k
>> Nothing -> do { k <- newKey kloc ;
>> HT.insert tbl str k ;
>> return k }
>>
>> occasionally, the second thread gets to perform the lookup before the first
>> has updated the cache, so both threads create a new entry and update the
>> cache.
>>
>> If you loop in the Haskell programme, after the first round each thread
>> definitely finds an entry for "()", so the cache isn't updated anymore.
>
> That sounds plausible. Do you see any workaround? Perhaps repeatedly evaluating typeOf?
typeOf' seems to be a working workaround:
typeOf' val
| t1 == t2 = t1
| otherwise = typeOf' val
where
t1 = typeOf'' val
t2 = typeOf''' val
{-# NOINLINE typeOf' #-}
typeOf'' x = typeOf x
{-# NOINLINE typeOf'' #-}
typeOf''' x = typeOf x
{-# NOINLINE typeOf''' #-}
Jean
More information about the Glasgow-haskell-users
mailing list