X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=Foreign%2FForeignPtr.hs;h=53275c10a2ea02e2ba29391721f0e104da979a79;hb=e0062ebb3e48285f0649cd3ef9d71135829ba965;hp=4870a46faac80551240a2d2aea55bb17dfcee5f3;hpb=06fa098610391a8fa1cad55694de9a2e44494fc4;p=ghc-base.git diff --git a/Foreign/ForeignPtr.hs b/Foreign/ForeignPtr.hs index 4870a46..53275c1 100644 --- a/Foreign/ForeignPtr.hs +++ b/Foreign/ForeignPtr.hs @@ -1,4 +1,4 @@ -{-# OPTIONS -fno-implicit-prelude #-} +{-# OPTIONS_GHC -fno-implicit-prelude #-} ----------------------------------------------------------------------------- -- | -- Module : Foreign.ForeignPtr @@ -19,19 +19,34 @@ module Foreign.ForeignPtr ( -- * Finalised data pointers ForeignPtr + , FinalizerPtr +#ifdef __HUGS__ + , FinalizerEnvPtr +#endif + -- ** Basic operations , newForeignPtr + , newForeignPtr_ , addForeignPtrFinalizer +#ifdef __HUGS__ + , newForeignPtrEnv + , addForeignPtrFinalizerEnv +#endif , withForeignPtr - , foreignPtrToPtr + +#ifdef __GLASGOW_HASKELL__ + , finalizeForeignPtr +#endif + + -- ** Low-level operations + , unsafeForeignPtrToPtr , touchForeignPtr , castForeignPtr -#ifndef __NHC__ + -- ** Allocating managed memory , mallocForeignPtr , mallocForeignPtrBytes , mallocForeignPtrArray , mallocForeignPtrArray0 -#endif ) where @@ -40,12 +55,16 @@ import Foreign.Ptr #ifdef __NHC__ import NHC.FFI ( ForeignPtr + , FinalizerPtr , newForeignPtr + , newForeignPtr_ , addForeignPtrFinalizer , withForeignPtr - , foreignPtrToPtr + , unsafeForeignPtrToPtr , touchForeignPtr , castForeignPtr + , Storable(sizeOf) + , malloc, mallocBytes, finalizerFree ) #endif @@ -67,22 +86,32 @@ import GHC.ForeignPtr #if !defined(__NHC__) && !defined(__GLASGOW_HASKELL__) import Foreign.Marshal.Alloc ( malloc, mallocBytes, finalizerFree ) -import Data.Dynamic - -#include "Dynamic.h" -INSTANCE_TYPEABLE1(ForeignPtr,foreignPtrTc,"ForeignPtr") instance Eq (ForeignPtr a) where - p == q = foreignPtrToPtr p == foreignPtrToPtr q + p == q = unsafeForeignPtrToPtr p == unsafeForeignPtrToPtr q instance Ord (ForeignPtr a) where - compare p q = compare (foreignPtrToPtr p) (foreignPtrToPtr q) + compare p q = compare (unsafeForeignPtrToPtr p) (unsafeForeignPtrToPtr q) instance Show (ForeignPtr a) where - showsPrec p f = showsPrec p (foreignPtrToPtr f) + showsPrec p f = showsPrec p (unsafeForeignPtrToPtr f) #endif + #ifndef __NHC__ +newForeignPtr :: FinalizerPtr a -> Ptr a -> IO (ForeignPtr a) +-- ^Turns a plain memory reference into a foreign pointer, and +-- associates a finaliser with the reference. The finaliser will be executed +-- after the last reference to the foreign object is dropped. Note that there +-- is no guarantee on how soon the finaliser is executed after the last +-- reference was dropped; this depends on the details of the Haskell storage +-- manager. The only guarantee is that the finaliser runs before the program +-- terminates. +newForeignPtr finalizer p + = do fObj <- newForeignPtr_ p + addForeignPtrFinalizer finalizer fObj + return fObj + withForeignPtr :: ForeignPtr a -> (Ptr a -> IO b) -> IO b -- ^This is a way to look at the pointer living inside a -- foreign object. This function takes a function which is @@ -93,8 +122,8 @@ withForeignPtr :: ForeignPtr a -> (Ptr a -> IO b) -> IO b -- the action and use it after the action completes. All uses -- of the pointer should be inside the -- 'withForeignPtr' bracket. The reason for --- this unsafety is the same as for --- 'foreignPtrToPtr' below: the finalizer +-- this unsafeness is the same as for +-- 'unsafeForeignPtrToPtr' below: the finalizer -- may run earlier than expected, because the compiler can only -- track usage of the 'ForeignPtr' object, not -- a 'Ptr' object made from it. @@ -104,30 +133,49 @@ withForeignPtr :: ForeignPtr a -> (Ptr a -> IO b) -> IO b -- 'ForeignPtr', using the operations from the -- 'Storable' class. withForeignPtr fo io - = do r <- io (foreignPtrToPtr fo) + = do r <- io (unsafeForeignPtrToPtr fo) touchForeignPtr fo return r #endif /* ! __NHC__ */ #ifdef __HUGS__ +-- | This variant of 'newForeignPtr' adds a finalizer that expects an +-- environment in addition to the finalized pointer. The environment +-- that will be passed to the finalizer is fixed by the second argument to +-- 'newForeignPtrEnv'. +newForeignPtrEnv :: + FinalizerEnvPtr env a -> Ptr env -> Ptr a -> IO (ForeignPtr a) +newForeignPtrEnv finalizer env p + = do fObj <- newForeignPtr_ p + addForeignPtrFinalizerEnv finalizer env fObj + return fObj +#endif /* __HUGS__ */ + +#ifndef __GLASGOW_HASKELL__ mallocForeignPtr :: Storable a => IO (ForeignPtr a) mallocForeignPtr = do r <- malloc - newForeignPtr r finalizerFree + newForeignPtr finalizerFree r mallocForeignPtrBytes :: Int -> IO (ForeignPtr a) mallocForeignPtrBytes n = do r <- mallocBytes n - newForeignPtr r finalizerFree -#endif /* __HUGS__ */ + newForeignPtr finalizerFree r +#endif /* !__GLASGOW_HASKELL__ */ -#ifndef __NHC__ +-- | This function is similar to 'Foreign.Marshal.Array.mallocArray', +-- but yields a memory area that has a finalizer attached that releases +-- the memory area. As with 'mallocForeignPtr', it is not guaranteed that +-- the block of memory was allocated by 'Foreign.Marshal.Alloc.malloc'. mallocForeignPtrArray :: Storable a => Int -> IO (ForeignPtr a) mallocForeignPtrArray = doMalloc undefined where - doMalloc :: Storable a => a -> Int -> IO (ForeignPtr a) + doMalloc :: Storable b => b -> Int -> IO (ForeignPtr b) doMalloc dummy size = mallocForeignPtrBytes (size * sizeOf dummy) +-- | This function is similar to 'Foreign.Marshal.Array.mallocArray0', +-- but yields a memory area that has a finalizer attached that releases +-- the memory area. As with 'mallocForeignPtr', it is not guaranteed that +-- the block of memory was allocated by 'Foreign.Marshal.Alloc.malloc'. mallocForeignPtrArray0 :: Storable a => Int -> IO (ForeignPtr a) mallocForeignPtrArray0 size = mallocForeignPtrArray (size + 1) -#endif