On Sun, 2009-01-11 at 17:43 -0800, Patrick Perry wrote:
The "touchForeignPtr" is there to keep the garbage collector from deallocating the memory before we have a chance to read 'e'. My question is the following: Is the `seq` on `io` necessary (from a safety standpoint)? Or am I just being paranoid?
touchForeignPtr :: ForeignPtr a -> IO () There is no need to seq the returned () value. It's the side effect of touchForeignPtr that provides the guarantee that you're after. So I think you could use: ... in inlinePerformIO $ do e <- peekElemOff p (i*inc) touchForeignPtr f return $! g e By the way, in your: IOVector n e = IOVector !ConjEnum !Int (ForeignPtr e)! (Ptr e)! Int! Do the (ForeignPtr e) and the (Ptr e) point to the same thing? They appear to be related because you dereference p but touch f. It used to be the ForeignPtr was slower to dereference than a Ptr and so caching it like this could make it faster (but then requires lots of careful thought about touchForeignPtr). These days ForeignPtr is just as fast and so you can use withForeignPtr and never have to worry about touchForeignPtr. You'll notice ByteString works this way. Duncan