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