[Haskell-cafe] FFI woes!

Robert Dockins robdockins at fastmail.fm
Thu Dec 16 10:43:45 EST 2004

> -- play a sample
> samplePlay :: SoundSample -> IO SamplePlayback
> samplePlay sample = do ch <- withForeignPtr sample (fsound_PlaySound (-1))
> 		       let spb = SP ch sample -- SamplePlaybackRaw
>                        mkWeakPtr spb (Just (samplePlaybackFinalizer spb))

 From the System.Mem.Weak docs for addFinalizer:

Note: adding a finalizer to a ForeignPtr using addFinalizer won't work 
as well as using
the specialised version addForeignPtrFinalizer because the latter 
version adds the finalizer
to the primitive ForeignPtr# object inside, whereas the generic 
addFinalizer will add the finalizer
to the box. Optimisations tend to remove the box, which may cause the 
finalizer to run earlier than
you intended. The same motivation justifies the existence of 
addMVarFinalizer and mkWeakIORef
(the non-unformity is accidental).

This note also applies to the use of mkWeakPtr.  So if you want to 
protect the raw pointer, using weak pointer finalizers is not the way to 
go, because of the problem with optimizations.  If you are going to use 
finalizers, you should use the ForeignPtr versions (that's the main 
reason why ForeignPtr exists).

The usage I suggested only used weak pointers to detect the fact that 
the foreign pointer had been garbage collected, and did not use 
finalizers at all.

More information about the Haskell-Cafe mailing list