Opened 5 months ago

Closed 3 months ago

#8502 closed task (fixed)

Document a surprising {{{unsafeDupablePerformIO}}} limitation.

Reported by: int-e Owned by:
Priority: normal Milestone: 7.8.1
Component: libraries/base Version: 7.6.3
Keywords: Cc: simonmar
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: Documentation bug Difficulty: Easy (less than 1 hour)
Test Case: Blocked By:
Blocking: Related Tickets:


We just discussed the following code on #ghc.

import System.IO.Unsafe
import Control.Concurrent.MVar
import Control.Concurrent
import GHC.Conc (par, pseq)

x :: MVar Int -> Int -> Int
x m a = unsafeDupablePerformIO $
    withMVar m $ \i -> do
        sum [1..1000000 + a] `seq` return i

main1 = do
    m <- newMVar 42
    let w = x m 0
    w `par` print w
spark: thread blocked indefinitely in an MVar operation

main2 = do
    m <- newMVar 42
    let w = x m 0
    forkIO $ print w
    forkIO $ print w
    print w
spark: <<loop>>
spark: <<loop>>

main = main2

This is not a bug; what happens is that the RTS suspends one of the duplicated computations of w, effectively killing the IO action that was passed to unsafeDupablePerformIO in the middle. This limitation of unsafeDupablePerformIO should be documented.

Attachments (1)

0001-Document-another-unsafeDupablePerformIO-limitation.patch (1.0 KB) - added by int-e 5 months ago.
proposed patch

Download all attachments as: .zip

Change History (5)

Changed 5 months ago by int-e

proposed patch

comment:1 Changed 5 months ago by int-e

The same limitation applies to unsafeIOToST, which is currently completely undocumented.

comment:2 Changed 5 months ago by simonmar

  • Cc simonmar added

comment:3 Changed 4 months ago by int-e

  • Status changed from new to patch

comment:4 Changed 3 months ago by thoughtpolice

  • Resolution set to fixed
  • Status changed from patch to closed

Merged, thanks!

Note: See TracTickets for help on using tickets.