[GHC] #367: Infinite loops can hang Concurrent Haskell
GHC
trac at galois.com
Fri Jan 13 06:38:12 EST 2006
#367: Infinite loops can hang Concurrent Haskell
-----------------------+----------------------------------------------------
Reporter: simonpj | Owner: nobody
Type: bug | Status: assigned
Priority: lowest | Milestone:
Component: Compiler | Version: 6.4.1
Severity: normal | Resolution: None
Keywords: | Os: Unknown
Difficulty: Unknown | Architecture: Unknown
-----------------------+----------------------------------------------------
Changes (by simonmar):
* architecture: => Unknown
* difficulty: => Unknown
* version: None => 6.4.1
* os: => Unknown
Old description:
> {{{
> An infinite loop that does not allocate can hang
> Concurrent Haskell, becuase no thread switching
> occurs. Demo code below (from Koen Claessen).
>
> Bites occasionally, but not often.
>
> Simon
>
>
> module Main where
>
> import Control.Concurrent
> ( forkIO
> , threadDelay
> , killThread
> , newEmptyMVar
> , takeMVar
> , putMVar
> )
>
> import Data.IORef
>
> import IO( hFlush, stdout )
>
> timeout :: Int -> a -> IO (Maybe a)
> timeout n x =
> do put "Race starts ..."
> resV <- newEmptyMVar
> pidV <- newEmptyMVar
>
> let waitAndFail =
> do put "Waiting ..."
> threadDelay n
> put "Done waiting!"
> putMVar resV Nothing
>
> eval =
> do put "Evaluating ..."
> x `seq` put "Done!"
> putMVar resV (Just x)
>
> -- used "mfix" here before but got non-termination
> problems
> -- (not sure they had anything to do with mfix)
> pid1 <- forkIO $ do pid2 <- takeMVar pidV
> eval
> killThread pid2
> pid2 <- forkIO $ do waitAndFail
> killThread pid1
> putMVar pidV pid2
>
> put "Blocking ..."
> takeMVar resV
>
> put s =
> do putStrLn s
> hFlush stdout
>
> main =
> do timeout 1 (sum (repeat 1))
> <<<
>
> The above program produces the following (expected
> result):
>
> >>>
> Race starts ...
> Blocking ...
> Evaluating ...
> Waiting ...
> Done waiting!
> <<<
>
> If you replace 'sum (repeat 1)' by 'last (repeat 1)' the
> program hangs.
>
> }}}
New description:
{{{
An infinite loop that does not allocate can hang
Concurrent Haskell, becuase no thread switching
occurs. Demo code below (from Koen Claessen).
Bites occasionally, but not often.
Simon
module Main where
import Control.Concurrent
( forkIO
, threadDelay
, killThread
, newEmptyMVar
, takeMVar
, putMVar
)
import Data.IORef
import IO( hFlush, stdout )
timeout :: Int -> a -> IO (Maybe a)
timeout n x =
do put "Race starts ..."
resV <- newEmptyMVar
pidV <- newEmptyMVar
let waitAndFail =
do put "Waiting ..."
threadDelay n
put "Done waiting!"
putMVar resV Nothing
eval =
do put "Evaluating ..."
x `seq` put "Done!"
putMVar resV (Just x)
-- used "mfix" here before but got non-termination
problems
-- (not sure they had anything to do with mfix)
pid1 <- forkIO $ do pid2 <- takeMVar pidV
eval
killThread pid2
pid2 <- forkIO $ do waitAndFail
killThread pid1
putMVar pidV pid2
put "Blocking ..."
takeMVar resV
put s =
do putStrLn s
hFlush stdout
main =
do timeout 1 (sum (repeat 1))
<<<
The above program produces the following (expected
result):
>>>
Race starts ...
Blocking ...
Evaluating ...
Waiting ...
Done waiting!
<<<
If you replace 'sum (repeat 1)' by 'last (repeat 1)' the
program hangs.
}}}
--
Ticket URL: <http://cvs.haskell.org/trac/ghc/ticket/367>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the Glasgow-haskell-bugs
mailing list