[Haskell-cafe] FFI woes!
Ben Rudiak-Gould
Benjamin.Rudiak-Gould at cl.cam.ac.uk
Thu Dec 16 10:08:57 EST 2004
Sebastian Sylvan wrote:
>Ben Rudiak-Gould wrote:
>>Why not spawn a thread which starts the playback, waits for it to
>>finish, and then exits, and wrap the whole thread in a call to
>>withForeignPtr? Then your finalizer won't be called prematurely.
>
>Well I could do this, but for one it would be cumbersome to stop
>playback.
I don't think it is. Let me try to specify the problem precisely to make
sure we're talking about the same thing. We have an interface something
like this:
loadSong :: String -> IO (Ptr SongRep)
playSong :: Ptr SongRep -> IO ()
stopPlaying :: Ptr SongRep -> IO () -- it will also stop by itself
isPlaying :: Ptr SongRep -> IO Bool
freeSong :: Ptr SongRep -> IO () -- unsafe if song is playing
and we want an interface like this:
loadSong' :: String -> IO Song
playSong' :: Song -> IO ()
stopPlaying' :: Song -> IO ()
isPlaying' :: Song -> IO Bool
I think this implementation will work:
type Song = ForeignPtr SongRep
loadSong' name =
loadSong name >>= newForeignPtr freeSong
playSong' song =
forkIO (withForeignPtr song (\s -> playSong s >> waitForSilence s))
waitForSilence s =
do threadDelay 500000
b <- isPlaying s
when b (waitForSilence s)
stopPlaying' song = withForeignPtr song stopPlaying
isPlaying' song = withForeignPtr song isPlaying
If you need the return value from playSong, this should also work:
playSong' song =
do rtn <- withForeignPtr song playSong
forkIO (withForeignPtr song waitForSilence)
return rtn
But this won't work, because the withForeignPtr call will return before
the thread exits:
brokenPlaySong' song =
withForeignPtr song (\s -> playSong >> forkIO (waitForSilence s))
-- Ben
More information about the Haskell-Cafe
mailing list