
On Thu, 16 Dec 2004 11:08:13 -0500, Robert Dockins
-- 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))
Ahh... look. You are returning a weak pointer! Those specifically allow the referenced object to be garbage collected. So the only references left to your SamplePlaybackRaw are (a) inside a weak pointer and (b) inside a finalizer closure. Such references are NOT considered reachable from the root set, and can thus be GCed (I am about 90% sure this is true about finalizers). You have arranged it so that the RTS can garbage collect spb, and thus the ch and sample, whenever it likes.
Well that shouldn't affect the functionality. The weak pointer was only a way of attatching a finalizer to the Playback object. It is true that I should probably wrap up the the SoundPlaybackRaw inside the SoundPlayback as well, to save CPU, but it shouldn't matter for the core functionality. It appears weak pointers don't really run the finalizer when I want them to run (they run too late!). Or maybe it's the finalizer for the ForeignPtr to the sound data which runs to early (I create it using newForeignPtr). Nevertheless, i couldn't get it to work when doing "strong" pointers either (StablePtr, cast to a Ptr, remove StablePtr, create ForeignPtr from Ptr and attach a finalizer). I really don't like the idea of having a background loop running all the time (I'd rather spawn one just before the GC tries to clean up the Playback). If I were okay with that I'd just spawn a new one for each Playback, which would be considerably cleaner I think than having a single loop with some sort of master database of playbacks... /S -- Sebastian Sylvan +46(0)736-818655 UIN: 44640862