Skip to content

deadlock with race #93

@lehins

Description

@lehins

This simple code results in a deadlock. Solution is to stick a yield inside the otherwise clause of the check function, but that's not always possible, since check can be pure function with a loop in it.

import Control.Concurrent.Async

someFunc :: IO ()
someFunc = do
  w <- pooledCheck 2
  if w == 2
    then putStrLn "Success"
    else putStrLn "Bug in implementation"

check :: Int -> Int -> IO Int
check step = go
  where go n | even n = return n
             | otherwise = go (n + step)

pooledCheck :: Int -> IO Int
pooledCheck step = do
  let f = check step
  either id id <$> race (f 1) (f 2)

Here is a repo that can be used to reproduce the issue: https://github.com/lehins/async-bug-repro running stack run should result in a deadlock

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions